package org.bouncycastle.pqc.jcajce.provider.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import junit.framework.TestCase;
import org.bouncycastle.pqc.jcajce.interfaces.SPHINCSPlusKey;
import org.bouncycastle.pqc.jcajce.interfaces.SPHINCSPlusPrivateKey;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
import org.bouncycastle.pqc.jcajce.spec.SPHINCSPlusParameterSpec;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.FixedSecureRandom;

/**
 * Test cases for the use of SPHINCS+ with the BCPQC provider.
 */
public class SphincsPlusTest
    extends TestCase
{
    // test vector courtesy the "Yawning Angel" GO implementation and the SUPERCOP reference implementation.
    byte[] msg = Strings.toByteArray("Cthulhu Fthagn --What a wonderful phrase!Cthulhu Fthagn --Say it and you're crazed!");

    public void setUp()
    {
        if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null)
        {
            Security.addProvider(new BouncyCastlePQCProvider());
        }
    }

//    public void testSphincsDefaultKeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");
//
//        kpg.initialize(new SPHINCSPlusKeyGenParameterSpec(), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SPHINCSPlusKey pub = (SPHINCSPlusKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData()));
//
//        SPHINCSPlusKey priv = (SPHINCSPlusKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SPHINCSPlus", "BCPQC");
//
//        SPHINCSPlusKey pub2 = (SPHINCSPlusKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData()));
//
//        SPHINCSPlusKey priv2 = (SPHINCSPlusKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData()));
//    }

    public void testPrivateKeyRecovery()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, new RiggedRandom());

        KeyPair kp = kpg.generateKeyPair();

        KeyFactory kFact = KeyFactory.getInstance("SPHINCSPlus", "BCPQC");

        SPHINCSPlusKey privKey = (SPHINCSPlusKey)kFact.generatePrivate(new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded()));

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);

        oOut.writeObject(privKey);

        oOut.close();

        ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));

        SPHINCSPlusKey privKey2 = (SPHINCSPlusKey)oIn.readObject();

        assertEquals(privKey, privKey2);

        assertEquals(kp.getPublic(), ((SPHINCSPlusPrivateKey)privKey2).getPublicKey());
        assertEquals(((SPHINCSPlusPrivateKey)privKey).getPublicKey(), ((SPHINCSPlusPrivateKey)privKey2).getPublicKey());
    }

    public void testPublicKeyRecovery()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, new RiggedRandom());

        KeyPair kp = kpg.generateKeyPair();

        KeyFactory kFact = KeyFactory.getInstance("SPHINCSPlus", "BCPQC");

        SPHINCSPlusKey pubKey = (SPHINCSPlusKey)kFact.generatePublic(new X509EncodedKeySpec(kp.getPublic().getEncoded()));

        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);

        oOut.writeObject(pubKey);

        oOut.close();

        ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));

        SPHINCSPlusKey pubKey2 = (SPHINCSPlusKey)oIn.readObject();

        assertEquals(pubKey, pubKey2);
    }

//    public void testSphincsDefaultSha2KeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");
//
//        kpg.initialize(new SPHINCSPlusKeyGenParameterSpec(SPHINCSPlusKeyGenParameterSpec.SHA512_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SPHINCSPlusKey pub = (SPHINCSPlusKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub.getKeyData()));
//
//        SPHINCSPlusKey priv = (SPHINCSPlusKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SPHINCSPlus", "BCPQC");
//
//        SPHINCSPlusKey pub2 = (SPHINCSPlusKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Pub, pub2.getKeyData()));
//
//        SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded());
//
//        assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512_256), SPHINCSPlusKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest());
//
//        SPHINCSPlusKey priv2 = (SPHINCSPlusKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha2Priv, priv2.getKeyData()));
//    }
//
//    public void testSphincsDefaultSha3KeyGen()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");
//
//        kpg.initialize(new SPHINCSPlusKeyGenParameterSpec(SPHINCSPlusKeyGenParameterSpec.SHA3_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        SPHINCSPlusKey pub = (SPHINCSPlusKey)kp.getPublic();
//
//        assertTrue(Arrays.areEqual(expSha3Pub, pub.getKeyData()));
//
//        SPHINCSPlusKey priv = (SPHINCSPlusKey)kp.getPrivate();
//
//        assertTrue(Arrays.areEqual(expSha3Priv, priv.getKeyData()));
//
//        KeyFactory keyFact = KeyFactory.getInstance("SPHINCSPlus", "BCPQC");
//
//        SPHINCSPlusKey pub2 = (SPHINCSPlusKey)keyFact.generatePublic(new X509EncodedKeySpec(pub.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha3Pub, pub2.getKeyData()));
//
//        SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(pub2.getEncoded());
//
//        assertEquals(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha3_256), SPHINCSPlusKeyParams.getInstance(pkInfo.getAlgorithm().getParameters()).getTreeDigest());
//
//        SPHINCSPlusKey priv2 = (SPHINCSPlusKey)keyFact.generatePrivate(new PKCS8EncodedKeySpec(priv.getEncoded()));
//
//        assertTrue(Arrays.areEqual(expSha3Priv, priv2.getKeyData()));
//    }
//
//    public void testSphincsSha2Signature()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");
//
//        kpg.initialize(new SPHINCSPlusKeyGenParameterSpec(SPHINCSPlusKeyGenParameterSpec.SHA512_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        Signature sig = Signature.getInstance("SHA512withSPHINCSPlus", "BCPQC");
//
//        sig.initSign(kp.getPrivate());
//
//        sig.update(msg, 0, msg.length);
//
//        byte[] s = sig.sign();
//
//        assertTrue(Arrays.areEqual(expSha2Sig, s));
//    }
//
//    public void testSphincsSha3Signature()
//        throws Exception
//    {
//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");
//
//        kpg.initialize(new SPHINCSPlusKeyGenParameterSpec(SPHINCSPlusKeyGenParameterSpec.SHA3_256), new RiggedRandom());
//
//        KeyPair kp = kpg.generateKeyPair();
//
//        Signature sig = Signature.getInstance("SHA3-512withSPHINCSPlus", "BCPQC");
//
//        sig.initSign(kp.getPrivate());
//
//        sig.update(msg, 0, msg.length);
//
//        byte[] s = sig.sign();
//
//        assertTrue(Arrays.areEqual(expSha3Sig, s));
//    }
//


    public void testSphincsRandomSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        byte[] expected = Hex.decode("0e0ce237e144bd229938e1e8ca4998899107cdcc5fa73ad44a76fbd40ac1beafe4448b4b7dd0c81b3188cb02e30dd12371c9fe414e95d5186335fa8a438f5cce307bdb9c4827e6a0159da9e4a2aae29ef5877fc79d50c53a8d0aabe2fbbdd490c69e11776dbe9d6e7440f3b32278684022c99cfdd4e935d976c099c3cac865149383436ac34e309f6d5b3094260b35422b86fe1879a28faf178f310a4af8d5d429b0aa525ba2f4c090ce58d8ebf2acd21c0456ff74e82dfa1d1a9e69c5c44c1f69fda5e681ebb245f03d018e3de38cae2a2628892fe74fc0a981594f8d168eca520285d2e320c4d2d0b23951e6ebe4e055b62534e6dabc5deb4ea28a63404ff1c34035a61cad7ebaa1b19ce7fcfe1dffbf3af5d35fc11383a5e3a543a39e137fcf6bb651201daed7d74ad94f2de9045a2cb7f4fadedb9ae685d3f22ebd4538dde00225ac84f182ce0cfb33bc03ffed6e99dd6322192b627f4939887d62e01f7f1d2b43b7df38f4a1a6ec515aa8be87c134d747666c6e8f31dd93e9db0aeff3e23e6d88f91eb627409928af5c808bffba26afd98cd6a9e683fc36e6006244bc491218b3fd833c4480a3012d4456229403f9f6001e3fb807b0dbf99013859fba26a97a7a043f1e20aca9f5162f4d9120247b166549812f319790bbd39aeccc2b536b3b7c5de626deae6beb65aba1eb626ed574edddfd742f3f74a8352a0c137f5db67148dab075e27c9e3b84fd070d87e6c0da75c27e240ee30cdbcfa9dcc22018a65667cccbaf4a1231bc7d7be5bd5d3a238ca69b389636b6335c83166c12579691063467cec5cde398fcf4c83fae7d185151428eefd3d2d7dcdc55af3f7afe6839e852a26046182751f56f5b4a8dcdf6c73d2b3d2ee633fb3ab2438fb1b8b957fc32a816825cd3aa6b566a52baf7ceaa159de418a4f51d2ab06e268d99cf588fb7045b3f14f66a6f47a74193790f9f7f14d445edcd71875ba8bc36168481790c32972641c5e9cab708f9935e303a15fd9dcb96cee98dade96a056d73c45c3f00d97a653cdf6cd9b7bebfc22dc7f7807712d0a8924bb48d3f3d5f189b436d262ddc779cfeccf90672f49fbd702873fad65acb23706efb1e04f7a7cdfab430087a6b7d3a747ac542264d17c21f9b4b2017068ccc269ca7628bc366e6e00ec3410e3778ea5cc7ceca210d79d81a6880c340f60efb0b54a47eeea3ad77108b2c643f19611a3841036fbf48846331979947599b6334a70489273a981463df78c793edd7bfd55a4a1238a35dcac20a9c703d9b9aa1c176347f4e1d3b40614dae90f78ae8e6403c7f7fff3f43d0292ed49147d7691b65099633ee0c2397852150d7f7a5c68831efef532d167fef283be8f66dc29b31b66768ec4885cb9a4a961389e37e7e5463a3db0c88cae46541458f82d37700ab615216e264bdd54a5cbc5c4b87e1ef4531c2f6bdc746232b97a8ae4acf7658ed860fe0a80bcadea600e6427f6c7b846b9c3276409297985eb1a634720731c304f03b50a40ac2448e0ecb8edfc925097ee2e09302cb3c0b7e2974acd6964eebbb9d8cfd3aa260b14d580765f9ef7773c800118085c8a123b4f18eb4ed13a8d6fdd11219d95bc12f4a09f87ebe572af327f450127ce2f4ac9f85d4ac2c4623e299a85919f021ee3128b814948d8a399aa42d61a3b8ea995ae2085c3576c3e06443e26a1e92b37e9289f5d1dd1d30636a18ff1d35f7f675958f8817002983442f826573e5f2dae5de90ea9680034d38a719ac1a484c5f14f8ac298d51478bde1a7bee06b68b645dbd645077d07ac6047ee834d8233cfde8a851f6ce7b25f522e4bdb32daf593d9e9a25ba489b25d4d0b927c2f5342496a34472737469c766600354955da2e253de9511bfb4d41b824623567241e97338584ebb0f3413a35348fb716f789d30c6cd74f1c98c868cbf3f833dbbd9e2691901068693cb6485e7c86a8d86e9884bf36b14f45e995f265cfa608df37492ea3e25f8a9c6087ac8512d7349bd425b07fed4b54c7227ebbb047f8fec5d7548e953f626ddd877225d9bd98542f2839b83d38639dcf89f00d3f442aabcf625cd2ee216c4d5bc6f24ba181f6e8a5a4ed03ab028df0f095030bcfa5b0236ed7fe553f13ec720a18a31b77ef59e18619daf5ae8e5c68872ecc3833b0050ea0fc6a5ddce0c846b75f29d16fb312b1619bb71b477a0bbaa9c67aaf976428003f646cda1ca3e4186a8ea622db22dadd1aba7d94e846aaa0cd4d3d95cffc851524be80dc5d31094161ab806412690c646a00a4dcbb58f864931ba63d579a6e8beaa3a6514bb70e6877d1c40b5d4180f1acdee059bcc8760f804dfe41a098f2840062bfd3a64fdde1a3d90e4aa317d5a91619a9045ce7b3a2f8dc0c9551856ab963560b91f2496b166f50133d1c4f3869532cc2544db0f3f9b7ef418d0f4732cc31d0bee81391ce6da723b45059a96de6d77c9cf9b5fa30804959919af7d395a66a8c08a44245f70f7f6328d7ec52b673523b947c22179f23148eb750e2245d56473338a22a6e0842ab7d8065c935c615b4ac20a2f9d9462afd72abb345da4b07e1bf0a6cb8c04e18044b89ff16d601a290760f1de1a22b53da07c3ab2f56477c9a32ba838d672bd4c0b4fd0d6c9fcb2bbae5e638a350e4da33c5385246cc9dda35c883956ab297c70da05bf37d954408a8fca19521b6d39d8990b551677c218cdb8ce247cbc5d14beae1e59c6587ffc31a2b4d65a2a638d3bd7fccc47bd61a07f4696fc87b26f0809e3aeff5a6b952fd7d6625298c925f47d6246f4ed28b1542de9b9f5aa23cbd29a3dafcf68cd434b66f8e538358edee591fa68b37f3c3afc94942ffa767eaeeb7e2ebe639a268756330b5cc9ac3689f3ec1fb322784bb6dcf55ab26318c38f0ec2253f6600771c32227388b6bee4e78957a5115035bc19881da7d2b72b8c8aab7e0f2bc5aaf86b58895ec5acba50894dd861a914c39ad2c697e8623a11a287f8e308ef6e0c3ca912998c0f49ce1b7558917e97deb9915001ddca86d825c42ff0592cc9169891d479bd8f7cc31d7b5ed09171acf7703612368222980bee5e11d9c85b9065a638703c034e8c1a309e0f088c39402076bc3328e5896f57337ebbd4a5a6b6268b3c029cece534391d876833085026bb899669b5d6c37d0d51eaea1e28eeec3d0ea699bd7e4c419c7158819543340a5819e79b6c1e3d15891ad94befdf20cc9c632f698a9d9bdf6eba2e6cf691edac3855c9d111e0f856b02bb97a81290d8e9040245c293ae281601fc0ed99f9398bf1d670486020f73a63b466a392554c2ccd4a4d1c0a25993b7404f102cd455608e2740e04f0e0e9967beaa532288a80216fdc8303241f99a059da7cbb98a195334e68b9220824a48c89f2f3da04b3843c57814d276c2123e8df0d2d52348c4f0d3d150c0715fb1e1bad4e54b3a2819acf7ed6aa07869db2e291bd2e495f1bc804bdc7deec4892f06ccf1ff873e2e7cae4c38a45a2d1ada7e28ee066b522caa6b92674d1b524d09c51b6d98aed7544274e0c4ff7dcb3075a8f768c2a8d958ee9b36f5c63ac7b043393d7bf1e2490cae0a7fcba7ae9c5a082973efb8fea7513a052681b8dbb8c89f2b4a8a524d556ce1423bb1b02d9592941ac2d459376b37cdcc25e8627876820d489a0b8945923b02f7721dc1d3d4df67efc8e28ee4252da322b7d31b207267ece8387d000310adcbc63b6809571b9b4a3c513917a27cb086b27fd826a5f4fb8729ba16c110f445cadcd79168f74c01038e91301e89c9c7f92b2063caa3c0291bdff90517892b8bc5d704c7df7956fbb3540f9f6e7322f904e6b96c83be089b7038321f013a7d774d1a6cdb131daa866f39ef9a974306c9dbf7c30da7295fd7620187204ab85af7049331629d8fdaf2155c67742303f9fe37f0c11fbf6ffdcc566b14c7d7cc7d670e01800a53754c28955fd294a33f8e19f261c0a6f496973c219d7a142664fabf52ffc7c23c594a86d80b009123b37422bba11f241c61b84d8e26a7c9abec526efe70393313547fcd275519ae46fd3fd4c891172156960680518e05dd6cef1f6e962b111bbc14d30ad2bf3a29e1631665940b56b1e0340fb193ad7ef598befe61df3879bf56ed356e33814130217287685268141d5e77fa37ad1786be5eb0f7af8f956c4a85ac943c0dec3f941fba59083c0813becce5fe3e1864f3918f625ccb0e91f81369f1c03251eabc9628d11686fb3dcab1315b33f3348835be7b87df3bd022ced886a02d69dc2d537d1769865d830493824a71e7890a28298c9d7334a2620d27372849cb5eac2397c39463da08d7f81770cca90c134c7f24ab2de7512cc0413a43ccd600065f03c937703b06927d6cf00b971b8152cabab374761a380de81b92e46332734a6f7366a219bf06fdc71437f4c7f7c3c172dc29a81cb7890ec66e4a0973eed31895e1b1d7402857c11b30fa4f64e2dee0445ddf0936d3be0bc24983af7084fad82e12ef9affdd37cbdc1338f0ba7bd8b6a3b3af3d6111ed0bacf597bf805b63b9334aaffd5a9b571cac426cad1995fc8f64811ff6d1026f3adb8091c5b0ea630267a9881fd991f6535b30de5e6b90a76cb5e5140508b53083a57f9c1b7db41a656f37efc3b767128aea320ec058704ce944d97584a83c47116da491fc81b3f418fda65118ada880ebe4a7152ab0f38bfe4363c3a1e11ca2843f449c521b68ec8905a07876da75e1e55f63b5f8e6624efbbf660d710415e70548ce26859ee2137bd1f0b122a4c0430565d9704187f46f4407cba28043d87a88fd2f24aeea3037db9198ea622ae7672e18e135d8e120a5e2840b436a2e0fe547a16c4e3ea7fdfed67d462d1cc28ad3c1f298ab3eb14e56a4a512ec0eaa171e2d70bdb825905b335fcbd80cd03f0941d5393c8ffc305ad8ba54d59aea3e48ca8c7856e7e13739e063e43b8e5e505bc0c4f59c2bb7c5d8edb93cdfa9a2018c92d92e3b58b6ce7943eb1627c7ac4b2040bc8a3cd30728afe43d2ffcf34639742051d3254d73e76e5e6966e0ba631df96ae7692370a456240b1aef87df105496dd085e1a83dddaaf2f3646eb78ac85d8794b30d52b37eb8dcc4d0929646d78fa4f846b5e1ea1ff56f5fcf39a5748565c9245e4f356163d96bc92eb9382a325c023733d62a474290b505f9cad76c39ec14a999dfff4f18942686ca21fdf5919436598bf194b599cc564beec11273270489540857b4ed8268a44e8d2b3b9c7b55edd45d6ab3743f7d12b5784da54c546dd7bc7c60be8cb9e14c25353c13c1e355044dc2f979169acca94b293f2ffb15f9376a6b03cd94421044b34845b89beaf53a0801ede176a3fc62a6c5b0935a3ec30cd1381549b744f3729acda9ca75b24663a01ca6e9ff52095ece8d0b07d6efc831b2617884c1219caba9d75bc77911ea573bc43bdf4ea5e05a4f2bc4e407f349d8a6f10f9b83348e8aca70a9985eb4e6a90bdc77dff9afa3a5e6d2776d119291860bcd33808bf24e710d1c65cbc325d2b5e9ad47af57681f4842857c74a018c92794455b55306caad5a1322b248e26f819ad3313c3efaaf9b937f63c26cd028997c60191a99e2c7bae73c8b1bfdf0e2471ddf3e609596a9de1c133b430cb7b6f9f2b3f22e4073c4d2ee4e16d23a1cecd5403231ced66dbd2294a2273ceb31b90de1478ef02a61da9a55d4ad90e085795e3aa73ff54b1960ca47a1d2d3b5da1700b1d6a1bbda3aa93b1b39036cdda6d73f10a55bb65f1f23c642c6663d675f33edd123c2173805a31fa8c521965e35d9f2ba3ed73a306935e495fc982b61d5c53590e2f2ef74639e9c3080f299185e450525ed2faef1442f1db54cb4c66d35439a12b7730327179ec56140595c390ad9fc3deb7a583dba44bd8721ff099efde1629501f6afc557ca50d25dbd3e17b8649cd79595f81c51c9eef8d7d964a0f1f9b649ee2dd66fa918b35f722301b70267913fab1c36d4985ad9800ffa30b540148bbfa8c7a7483aae5cd4e196ffe637541f55b32ae5d4a7c77ac4eb012f3ce3d5eb61b101925cdf4339cad2e6071ab328735819eb944dcfcca9acda9225c4a01bf1befc685131c9347356a70d302b762fe7754922ca4f67e34f2a9dc0baba3ff8f7b831153b1cb074356be8dc694e519339e040a180113b3dcce315c25054a47f8d442b83ccdc33ae03f3e59b092144503ec66e7328da55d24cde316bab6ffb87dadba6d1a7f66ab227955c1a0512a64d4e733bb80671bb57e9b5d7b37f4aa0b8f0f443ac5983355761072a9180c0742915dda68698de7533641500c421873abe097e5d1107ffd14fe49475a495f110bef99a6deab1f3986df984106a2c7afbbac8db214228d0ac305b34dadf1eed9dd5dc9ee9f5c37814d64d0a9cf5876e599cd7ae317ca0e05f732baec04b8ae272640945cbaf618375ba6d815e41370f22cc8196464d16b873a8a3453fcd1282a48cb9567443c1d3f100409eef3557213c99bb95abfff4a1fdf8cbf295c0e96c6d8bdbb8db43c0a86f9a26239b92f2a15179da9550c755d4e232f081c07c13f7d66b7ef0e475702639f50b8aa85a3fa584acfd254f23e7751aa7869e4328d993b379a47b3790e0217cd24e196e24bdddf9535569f63c80d093bab3cea5f86dfd1392776b279c9654f6cc090d20044b5856b884893f848afb309cec42a42dd3f554cac4c38a160dcb4986e9bc4dcdd0b86acf39d07afff60d23cfefdd1c523ff3156c4cf9ce5a2e5a2923c81edc7f0894b869f57b0bd6915c03bc3b9e19ec73fd2d8bae648ca2cc07a1585b168dc8853f051d6c73454fbf17d87c2d99ae92a94f0c5515c96ff452b451f41b882d27c746757c50da01f254b29b4c2adef7acacf2b7300a5e39c028a745998c68fce1f22598e28dd7e0e0664bebe63f82a277779ba475fa806fb06f84e1450ae328311350839321c48a9857ccff3b3d719a8732e659f386b7c77e12ca156ff5169f3e847ffbce791ccdb3a96db30f837ef8449090aa00e8c24ff7e79f2c6971089efb5c538791a56e67650d75fdec9445e30356b1cc955b1768dabaeac6b5069a11f302e7217aa3edfb51aed308fa57120c701961b522cdc4289ea09b176d74da12ee17613056a195c83bede57f462bf8f2b4d241b08ec87666af8a5e920c9ca046dbffcdfcbc41417dddda1f056bd39d709a5fd87f64ca3b4044281f2be91f73d257f2914272f16316441ed806a5f59daa5d0256dbfc8699de29ec92c9bd1a8cb80601a759142e9c4f01bf8049b3ed5c90a50837f22e43e732e985edfad5576704f431ed4d7e5288ba2ceab233995cfa5770f0d8e10badfd96dd0710bd066e2d54d4510515cf314e12ef083c7d86b8390a25cde45bd268cd8d2a4f58ec17c5c97c54829b23cf3ac4556d2048e65ea7cba015d8bc2aab88ed031fc14488cf0651ccd2d6f6ebf735f4afda8d95c5995cdba375eecb446aa6e8e5684c3129a14664fabe165be22875f3c3624dceabb740d0d7e4984f05562fa008293a8faf704cdba18026234206c6891e6cc5d02f81f19713f7aa8e4eee1d9db248d0b1c930a2fcd9dc43dda5cd4e0eed2b8f517b43ff493cda189b84d6c218df276d2ee2dcdd88bf40fab201ffd8edec6a2b4a0d369506696198df7c8b6f9ec28610504b45b7e22959dfc4f02953162c0ca128b164c43795e9e2d8b9d33db20e77f9e0ea4ce7139a15ee65797b1efda585425fdbb8770496ab5ab90b5d49d78633362354c7d83607d63f861d4c27f51980212360d8af0ebf2ed9fcd72024c4bb25dd1349ecd37ea1f8e329b758b79059271a7353ad0bfba77ae388f1e8f3a2d8ea0b088825295dc4d1e23e02ed1d4045c8cb78e9b756e967ff4a3bfcb7e4aa07e527c4dba912333eb195d35a4fadcc4f9eb4352a8418060501607cca691a693f708b289951a183fed09a938c547bc723b849a5683a2b656386e44d542d4231ded560e8b28e3d3f6753d948ccc509cfcf55fc3f7831eabee768e3522de1e3c285e409b6a649d4c15c9209780bcd45713109a6646519abb21db428c305f880ed0e0be3abe673d7459d0044e219b234336fb42e8980da27c58a9316a56311fd27a0c04ddad2d4009dd143ae41a85df5c0649857e43987b8bc38e0d0dc79cb06c6c9070a1511788b624e936c38787f818302db7001aaad6fd831154ad09e83f5eac1287fb2b900dd39986737a0acacb35e23d133de070e99f2f6456629f15b40a4cadcf8f203d77b8da1dcad7a97a63f81eebe206d17ff0d1fb90bc617dc76f1205024e6e3967993968fc99f08d73d91c4520ce0de1a79c23384ae24627fe55494ecba6b17e86cbeb45025aff5bc3c4c142b0f09e7c29937e5976be1aae3b28957b630a7546901786af4dff344cedc9a7f6e15cb422908dae960f3434e7d7681667818fa15d4baab1b744a962f1c308fb8753a5294fa3f2da9fde12284828ced797ab74d66eb1ef6969520e4fcedaee6f9de990cab01186984d63c06e86d37237e88cf5d6d3efaad69329176feaa54b5046603834b788a9020dc1626635a92a49d3c9737c1cc81152470d02df631a33b50acda7431cc1c445444398853752c561909e191d9512ca1abf51eb876f2ce5dc20b0445c34a03fff2664ff1093e6888c94ab77325dffe2f8918e2910d49698ccb03118394c22f35f166b2cc312690684f104ebaeb4ad43d376ee5bfd8e8d1a5560c9a03136a21fdcb4c8f61583e87bae4f1c5253520ec968655ed3d737de33a782123dc6f1f90eb608391dd878cadd80a6f6b7480515540aacc9426ecf8df1b0d59ec59ea742e47ed7ff8ba9c48d0f949e525cb8593554c12e3357af267263a293fd26772156ecb70c7b4fc50e7136787da3980d55d222ef9b6b2a3445ba4ff0db03bf315e91c255887889e70d6ba2975a8494b3cc1b6c875366d913dc5256b1223afb1697bc407bd0dd26961ecb770067200f79394ec927c46291c427ec166c397b6e2567564673464eae3855770e5ebf0cfbe122eb8e059829e87db24549ea85595009c3db402bd50ef6c8593f5a712c0fe835169adef4a73083c035f0b7e7b82e3c03a7700610d52a120ce2ea3859b6b9192a495efe95223d3b96cf6fd3c098e59cf199ecd7a161777520ea31b386d414f33ee648d09785209460eade21bc95159666fadc67ca52720edfa7c7fb4f9ff342693f26f4517c0ab9f25f2f73cf8e7aed43b41e2ae8ce51b83a9662822990da9e7898b6d9c2346ccec83c5babf7f3090fc6205bc4a0ed1d74c25143f41b69e5e6b57531d8cf1d53ee5edc44abe7573fac8f031c58e3e23e4ba9699587597fbce05d35bf2fd8b56c95f58e392942f8e60d98a111308cc1f0dcf518b1586d6c38efa0e9988d9850cddbc154e47b24142f70ef30c7f33edbe366f477f92cbba59f3f0741016ac9fe7d001c143d7a72ae9de34ac28ccf7515b78756afad3f1a3779d250034031d87e7f9d2c9b1cc7c0289a00b357a3aa2319f92ccc052bdb5fa0fb5bc24836dfcf23894a9f3bae20b8de847617387f16eccab135c76d6cb4040ef76e3a40107f303521d4830353b1ef779c11d711c957efdec1404dc089d4230307e61c42cdfb1f5162595c07fe87559a1ab9c9183b0a152513e124acfa2a6f8d97418e0736ce6301136b2bc42a73efd8291530452ee8053716bcea7e102a70f0fc70c3e9e727fd332fa451aa17b63b7a8ad3429f2ed9b91d88291d3354ff02f7c7b5487b04321518e609924bc0bbb3757d310892df32abff833caf077ab63893252a7d296a8711ceae5a1f8b7aa2844b4ae609c86fb16c5eb67d6efe009e382563abe76977ebe86d0763c701a08a3b23ebd27f8c8547081fd40aaa1773c29765a0b047dfcba9fcfe803a91adaa8db1099b7bcbbd717497d217ee7547d8fe43e2225457fbca4af6ac8a8c29f0cf5e4163c2ed8debd99293eed426e02e0b199741a0b850ef5f82327c3348a366d27cf9ba1b8c1c9992990fd09184aedce9ca25446b2db2928b4243e7e99804adc009e9f7bab9b1cd61d46e1479a7baf7af52bd32488a72c30476cd8efee3f10e3375a28b44e8e751fa0c37e4400fd593e4b754df5fd9b6644062ab17726992fadb04502cb52d5de7c5aec59dccb40bfa5cf8a092d10ac15651f6a023c69864c0d5fe436e04d0395955d2289d7d176e8cb326b427845d51f8358bd0a3e9e3f5fd7e480843e392e7091f70407537773b0c6861a109a05ffaf62afe40619d44f1f33ba53ac92d3179d9c48819f12fe89f8a8a6fc4dd804d6b55a275fdc962969f4dffe3bd1fd1dbbfc69da93f111512bd677a428968cc3de65fc53536cc6c2b7f06e723a98775233e6f3cd2c56d64a1578f12dfb4ad5d7985911ed6e9be889be1b691bea5f696ede4469c7f5b68601592e5d59c18f8560e394020ade8c9a8cc999e4821713c25c240725999b80892941b062c7dfebdd37af1fa1b416c9b7490c9f2fffe6e68acb4c33403b265f468a4918897a0ce22ee95660f57a0b31a3d08b2d93467c57ad5ff0392fffd926781a6864136be12fc9e51c36449a4922f0b695d3eec94b5f26c5d71aa4a2c3e283ce3a05f976d941306e82794708d17e2fafd4c1575655288bea50d0f2337b782e8b6da034b30e32242cdf08576876b5bff54625feff1278584838f42cbc083a9f87c1cceb8343571dd2a90fdf4d62e0ab13a77254b0f54a81017ac054f60d4533724367eb652a1b37a82dda55a1822dccae6f2c5097035389ef3f35284089edd26f0c4eec88e92fdb8fcc54eaaecc5944cdead0a204c49c2aed71ae398eb90f620fbc34329df7820ab3e51a2c0eccb12263b93b914a957e15b6540fec7d006779ab69270e2ab23281fb2a4adf59949703f1cdbab4f26625aadc1662064c92352dcf55b9255fb50e1900237197b554b950a461c7c27f7306d8cb073c4896ae8479389819bcc98317815edc166ff8d96e36d69b6ab682a00d6dbc9f8d0380eb0c06941683a98266a2be6ac578183ac663b55479c82f427698e06ebf4a062d456ee5db57a7ded8fd602c35e65a3b664331522d7557a62dd1efb52a66a79c0598525aff28de3eafa53e25551f24760efd4ce9bc8cba91562a4eddec970b66074459cf80f9950a634c884cba86caafeb7eaaa71aae4c9b8b4e12d32f3f1bed0abb0174c6eae8a0c9d754c29c8292d6c7f75a9479dafe7ec898007c6a4a0f71bfde568dbd83278eed25aedc6e8b528b85728d1a9d483fee33a01b117fa78a37ccd1d5fb85907059beab31df2cc8718350e1f85ad4a3dc23f1c666a78d6f4c947a8ec48f0c7cf7fac5e2a476e025d3c32d745f68e4431dd05a9132ccce3ba8a6504e31b70dc753f20f9e10612d5326806d478b446cdb7ceaa45bae6d8e2fc108660f114dbfbcdf610fa5af00b5e4053081be8b4cb48cc90df48dd6b8a061076b30f40c05de4c66173acc09680e126441905aa63da235954b2ef9f294a09468d7bbd18f4c5455f3b242e3693ff250e550dcf479761a453a909b03f44d86cbf30f3b56d69646d771032157050c943622e4bffc6cdb04ce504f310997653a9862a8e835d0dff62ed703a12f1d0816332c0ca66fb1e75cf24d6088bb366b17854aafbf39285690abd68595cc93d5579d328edf6929d11471b9500f07761f736358f856c2a8a09668e52b488e834e4a063e730a7348d62a262b7d51db31977ff7434cd340913c5ff7eb64e29dd9ca1dc6e0a278c492e0cc9ad6df9ffccbda185cf8bf47736f048b3b2fb9ff0581393a73819c823f690ced45461be747464d0d49e4bcfdc670f57eea1f39fd7ca806069cca989e4775b82ee270b80b6868122b252866158464b8c90e9e5a1843d9eebdce18dd8d0a8464a1709912fa38704bed3a23cf4253145cabd5eb1b219ad1e376b588f578a0fff101ee1dc132385e02e549f603b07225cc48963e5a720039b68e3f37a00630aa72fc5530413932e7df3b16969e486d468627cd8f58d791fa8f0d741fa95e07aadf16789d5c52b0de228d82b59eaefc716fb401477f759a14929b8aa8b5a0e3ad81f5a6ee67beda7408d8b27b7356c37850ac77ac1c663cd0695f75d372c896e75ceb352e55848d65b0f51c1bb3c4f9ef87b5863c0b96d1d48f60cb656e555e9a607516a8fce8a7f8fc5bf516b3e14d0a9f49c9ec1cc5df017fae7e2a6e40fd5e93b4ee1a0e65786197429efba537d751ea07b3e553a784aa3e5ac9db32b11dbded93625021914eb703e5655458fbf54a0d02509afb6f23ef5c5a72ff6fb3d20909a1f751319d879c72d213660d99e11f3aee6abe445371a962309fbd3ab9cd02ca6b19a696059198a150c2a46dbc8a7f4351c52c7a8d251d770c6dc4e0a3c9a2ab3ffa253682432d07dd759535a49187972eece845cfbd8deaef83aa6c9aae0fac578fc044b0916bd3d8b032851f81f8fbddf8a3d156fce99b380756f0e1c2da7786957a7abe5f3f22dea5b85d950ff23e577247e499574eeaca5dc05a6441974f5c750ce23190b5eb70d0cf17d6968ad0822d6db56b350d066ce59fbf1e15b35e57791372ea7549b63c91a10d33bd5bd5247a36453a766f1dbddb927f38fd4806870f0a80cef507b43749ad4067f98d5e326e8ba2b816fd7756b24fbde2197fba64d3c13f83063b14f196f84ecc4193a5df2e483e0fba539b5040c4347b6e977864f83f391428657b1664d21c3a92593d46e555c452541e0e127c983acd74026d784d5eeeb41e7ef105dea7111258abfacf4b37854c1f21de3bb6cc65901be6704b30f19c7da00416368b7a08cbdc85558e634cc033d3879eb04acd92cba1254a9052bf7616227c83f0abc2d0f8c3af23495d76c2c989834358fa7740b1781579c7f90162370a2922f519918ad5036bf3d425f0203a201f765a88b54edf596bc6fc3628b996d94349b90a3b71df15a1aa6270cad5b79a89f6cc244a595fc24a5f2d9ee9c7bcde86f6de4456e90a792b8ddcf75076dd8e098ff2d87ac5fa23e02fba5fb15a8d04cf95e6fde79e22baf24cd8cb556996b84a623a359612f1c312277825ce00ca2769000745dee5aaa581ab662e01b6e48e804d66503f967211a16cd4d9ff424c869a58b4979ae93d55bf72d108ac05ffead6f0467a1e6e4699424b3ccf60d53cb51ecd96b47b3a3bb51648f99610033af38813bf8878780f90c7b30cac097ef15234116c0b6184a9f7e4a73ab71942d0e3b48fd29f716757517f807ff33b4810ebeacba21e45d439c4c0e5215e1d871e4e1a58c51af3d9f35c70f54f5e8c03f171a4003372b60e44b81b781592125de0c05e1d7875e62c2abf210f33497a82333eeac71ba9d5ccf38215d55d116fff3043762ea19d1cc7152e41bf8a810d63a6386840446803bea8bfcf4d07a1cdc58090b7850a21a572fc9a7f5784db92be827f353a1781ce79b0cdb049ef367c6f3e9b293eb1860fc56c33c4409dc7f48000e009b106d2606db5014e86c61ee74054e6d54971b53f6cb20e705b5226247981185d0900cac15cceeca24e24ebbb998b9d8b8d9cd9f1075abd975a1828e763fd164b32a6fdcffff180d39bce964224fe01eeae798ea4e516aa1930ba3293c9f62e198d31f551d5f0ff3e56e8a65d265e20002e86ca0ee8e5b9274a334c8864c35dfb130432fcda74935610102b2bbb8947f387dba3b8bcf7f136b567b72123efdc365169ac2950c6c4351ee580b76658dfd185faf35311d00b8d283dbf600b645efa6fd1e0482c2a01e69b44458fd2d02101ff1558c5c8731d9aac68a9926fbf0cfbc3f473e6bc747487eb952a7bf437c887755fea7348d7eabb616a8b174d9c01e21a87a3ff4a53e58a10ce495eac01135b1e9afe8597206860a8619f814d7d9ab03829be17775ba0fbd1b5227357fb1be1d660f7992072d021d92858b1fc4fa50ab50cf37d714ee836dd30f9b134904c430ae3a407052a6a5a44f411136e6e4f0e945ef1cce27708114f04eef611aebe2f8e7d4588a101fdc53d85d64d1ac0a04b5d9521ba441ef8393dac2cad5c6f4d36f6b86a42e8ddb2eaf47f91bdafdf81c6410e0cfc5496ea9cfc36782247866d3543597c52bdc7e66b68b99eb876667e459c8ed9c67664971afe390012ee1bab2b96861919882020e6f42b1e0292f30cd0cff0c9c1080740a249675db2cd70496837132f1aedf923f45966a5ab3d7dbb9cd9d2369e622587423dcf221cb2ff92017479eeff2a4c8e4bec7a77c265c9146f7b656f49aac3a05746306d2b0fa9f3ebd95557b21290f26b2bfdc6c32872f2624ed38dac278690c5f4cb7d4e55910a9f9789d8e2eacb70430ac8afa2ecca1a6ce3556abb18c2527290f2b82d2fee73043e79fca7c07a946576957426cd825686381d57d522ef0a2df02fcf3d393a9935d4abe69d19a8aeb67d1571c20ffb4f7f19ab1c519e5b519f66edb2db6a0ded7b3d189cda86d91e50722e1d628fbd0a8ced4af8040952eb0c0acc80e2dd36afa0b19f1d3826a45eaf12bad7d4fb7710b584238783500548e82e75992b84404b20552702b46b401f6ec463cbfd18fd0075ca679bcd71d491167b76968aea25aaa2f640a94c0ef404cfcef91043216d7eac6f43577659d594f0f7e0f735382dca7e3fad55155bc3ed568f3ad6811fb090f952fe540e934f0a38ee0939f9b0dc047ab1b55a30096caf7d914ecddd083d5936b7e0553a55d9a9a4c2569658a7fa7e074c04641cf579327d010493d2cd21f0c6f8f5d5297185618ffac7cb129317d75a802c2e5a397d3121d02da3115f62ce34a60f063ad30842a428dd51187f191681b987a9525010ce07bbc0bee52055e6aff3b30dfd2d66928af9f86042637b2d00768b0e7c3baee50e2a79deec3deafc9ab5e4891fbaf7eaad047dcdeb8cdc09c88298eb4a527077358a0c3b4a01f80a95c2fc77f4401a763dce47ed7ebd4aa9bf8019b1a86c89696d3741a8bf818c864044ea92147c6fbada8dbe0ee81605eeb5ffe34bf40b9a11cd1a1c5a94892cd78a9b2c3f9cfdc891deebfdd3d351059610c54f751e058645d05f0e7882c9abc617d10f587895c7dbfa9a41052adaf79fcdbe71053a374e9be1678fa2933700cde075c2845d3378d09421c1fa4416e9fcb429b0e3839c6c06c24b66138ddea79f054c1b36bb208bf3d190f5b481c90296c179cdc90323d4d37cd15cebab55fb998f2a67acb64b3704cf724e20f2c9d43ad3e04701a9222d3439769c48a19254ec40281fbb39d03e63840f0376d7c996fa01126ca60605b478337ca58b0a0afeedb555a36d97d89ddc38da193a42204b2833fba573039a887a18df01eb746a4778448849305d6fd38366ae551111f210eeefe1792ce7cdca926b023d90df294a09c26af9b23bfe5e3866f2e96fd1683a291cc074afbf884ef77ef3ef08ea7fe1239eb824321b82df92824f56294d178c944d811f0aaed3f0cb3e1aa933ad136cf5573b8377295a9d55aadb489f73564ed7f84878ca3e9639db05d7dc8c41a9c5d79f48d8469f0725b27f1a9aaad5f6f6f7184d12005b7f88a012d7c4e3a22b64fea9f4ad5b7db311a37d7646f569b33a1b3295e2ebab6f25994eb20f7847ff5053571e65ed21bca41d8253b49105a5a76e24c2e9e6dfd1d6295722160fea75ad231bf056eb5d41fc15a7ac444adb597d7f92caabb8d05f63c4019c63234008c5df590fa3792c93d0df3a375e62e339ceaaa6ad83470a11acfcfe8cda523b21b9b3ed976e02c27dfd2469f148acb43654729a4f74ff4fdaefaebd1370ec18b6eb920a56f41124affdc247212eee4fcdff8fe116629c2b55f6b899bdcdedc99e94f60f6c709234e2d319f2bd32aa0df331dde409831a4839ab07be282ace358063b5a3389b81b211e0e2416a74babd50aa77b9ee6c2cf97befb486670216e8d227d6f54e3941fd6f3208a97ea18efe90a2db53fa4c7509b1e0ed29a107247e89838a97427ff00878743197b5e7e557097851bc5c945e3c15e48c6f6f9e3519f7434b3bc4052e53c5ed2589fa7a1f23d8344033200610a23db094059096da508df9404f8fd254e603be6a342949ac63d17786661f976744cc0575bc48733957bf4dbeb2c6ba9cd48b7149d89720136a008087b898ab0d30f662cc79d99c9982a95c0cf4279382cbfec0c2ef4e126971c71380080a1c80b4f70132cd21956b26f2604d8f370e92dda203a7cdb5b86ea32b47a8f436042ba02fc2b06ff3f7b1728a1a02ba2987d598d38f3e2c1ebd8b4aaaab0c16b89746752260e53c076534b436cb4447be396276ef855bf5f0f80b7cc05f8efdcfa1e7270d64eb42580274fdcb588fcb2cc00026d46114a38e84c6aa94b39519f62550b235b5f6c9fe8ab39ecff3ed74cf36e8ce20f9c2088feb043dee8b0715bb51c38c96b2b18aac03ae1a04a47c85779de147408a4b82668861266258dac1e7be6793e293a4c957077642225ed5a90cdcdb2979989b7f768045881e1bcbfaa9fd7967efb0fb3ebb7358b71cbf97334095d8f306156d22c6e7f308fd0a22cdc5f293bc6b7c713e1b7703dae02be839196bd98ae0a0d233ea0f7a7838eb759e5d682e5b418a23ec7e6b8fc908c9f5d8d2d961eb9bb2b3cf5dd08bada70c0d9c09656a9a22093c1cfca302bd4270b941ce1bd84c72240e2bdea9407d7803c80de28b0b9e75ff33319c8e770f228bf48ae106e3d694860cf8caacd72134b16cb98703d66dc7cdfd417c154cebfaea1fee8dfe373e624f66dcaef754f1597790bb97fc9415e813d344d7f1454a66a3d7ccf5f4fd747854a2f360e58400953282798fcbecc76b352a3e8e164c56d281eb0fc350fc2413553b8bedd6d8c8b2ca3a1885b7a8d5791ef7e202027bed636ebc3fab8035923b93743979646441c60bcf3062acc7b6e69cc13795571c39a8e39db512b40ddb01b552dbc8373ccc3f61f80cd017dd5b5cb0cc3ec7352800a59b427f532f1e087b2a3f389c14c814604098df11f54029ce6d967fb67cdc542ec229e251cdeaff68ab09fab31e368320a2485c96387d2e69da9e7351d0f3bb48dd6199557a8e2407deb567724619f914940cae38c78b6f87b4de2cbcc972a0c11ec91f067b009ea501c67987cb441f2e1b4ba6e97560f72f6b5004e9820c413b0c8ced49ae08de44fb4565eabb9c2177bc2fa44e23d2771d60adec574990d131646b133e59f32be4f6670183652b62257a096caf2dee2cf486613ca1627d735a0364fb1608d39c496d55ac63af7149212206d48894c9c19a6dff47e03fd49f53a3d920d7c1fb3ffad5984a922e2efbee2c7a334a8f917058f5f9b34eb901d1152c6e4d143359d6bff121d1371b8a8b7d7fb5c67cb53d2772d22dc5c0dd75d4889ab599333f4a2bfeab33e4d8f303b132de64feaeee72be80da1f5ac6d2a9a6239080f6faf8c9306284787387fb0d452f6851246bc1c4817838b2d5b1fabfaace02dc91360bce02b3392d867247af70a25bfc514b3b7b883ca96d3c32dc5b65d4f5e5500c7801e3f41b085ff202d98b9e62acc5410df023a1201a6928efeee97752f4f864af68ff9fedfcd76416afbf3aa7d9da990416056b8475cc39f353a36bfaa664ae51c405be5b0618ba1087af466d5469b6735675037682fca41af953a2d3755078828be41e185e97d05687ebda0113105d31be2ff0c1d201541b7d7371d69863c78d5698a562386f978f1d3a95689a1dcf7678b3e0c5c5c0787747f357fcf524369e34714759251bff73d1839d3e36c2b6ca80cbaef817281d53cca2c0da5b51d925036b02cc6d765caffb046571d96f56306bc2ab758588d3f8304f7ed304840019eb14fe4f0ca54d453f6abe7339bca9a2d49fa86d87cd0b66fad50841926cce59a9d8c6be8c5dd081ec88e140f79a4cc2cb03112692591643e32b71b01ba88a3924b8488b11db594a0ad67e2feef8c8de3d0d5d79d765366f5865ec8d4459e510c4fcee7d1f0d7c10e89234f83c8fc3aad7418f23805374d6b54f0569fb1fbb0ccef8ae191d23d60ed4ffaa97b81560bdbb2c7024cf2b6a88ca5e9421cf2203db97870f7646c74c5524ea843c6fde674a691922a4a300001c6d457c738cb5ee261d2f42c73a89d48d6154c1b0446fb96b1093bf77cf916dff70c41a276b0d7cb9bc7c38dfe2dd52d7428a0e8947e9dc06047b00afe7b6f3a18076292f507ecac572bcf7648b36f5899f7f45f32f8655d75ebb282bc4d2be48cb61e8aeba5dbe14794b68103d24ce062f7693a5a130219a630d18b74a4d3af98aeb12cb1fe0173185fdce2c4d95f43002243d11f43c75b0efbe0cf17e8da2ed974cf0248f31d50fe888acc4bef57590cf17280611e0299d3fc24ee12f9350a2328ccd6e06e1762b61510368b6f94aae109c7647686e3511885d11ef0416da0102fb040dd74637acc8f0de16dbc52bbe43148eedd587888ca674c032ba462325acdeb3929db8d8ecc1123059b9c2ef3541bc5c0608beadf4fd64f28723e588d5b012d21c56340cbc9aad26984f6f147b50d22c3047ff689687be5fcc3950581449c1901d4f5a19381b014caaf20818d7980e226157bf333ae2b02c5dc0bad3007805bbdea0297366ae1a0037c13764eb3eb8f1e7a0c3585ac7570dbc0d13d8083a83d2deee976511b2b75577b5db25f7f323b05957144d7be8e80346b0bc925ea5da6da50b8727e3e99c0313192b552d31c485f62706c5e368263ff1d319f10e282be3b5a7683eb27e1f3d8941bb67cbf7de26e11517e011c669550d47c1101cde7d672289f7c5e924ea2890399495db681d9e360a486ae1dcc9d9c9776a2681d5fb4d4a900d252a3ac0f17bce76b319b123fea56ea430b5c68a593e7fda1bdeadcb6c7b73b12eed557159b0e292c37f7547fcd701df26eefc78ab87027be8ffd75aa13f2b47d0608a1b962f52da02022db62951d32bfd36a31c2194f08f975faac69ee59e8850e2a715c25e9604300bd0fa4ec9f08fd16f6d0d7d579f5ae3f1f99243e3c69d8ef9e2d2ee4203075289dac2ed4f7cfd6f2cfb1aeff7ed2cfa62d88bae0dc697069b67bd0b50eba0ddb86eff864ddeacb26cca61e42306498e4e620edc144b48782df8fcf28f08e6f1d8df951ddcd27b53b79cd4c9892ce581139ac7d51bb7f6b85139b5403f2bd1569f7627244ad156eec4d1ad84ef0ca4d9ae0b4797d3a01792bddd7cfa59df5e0adbfebd44df77d4f5ff830366006f8d74822037979c80f793c78bd807ea0ad79406293685f38215a5c79bc65d1a59e8fd6a52cf25aac2b036a5fe6e5af6aea485663ad8107a77c2f0385196ecdd0c36641bb0f45d9687616d5ef3ef91d7c00f3adc1297822f5e421e318cb16697757d79f0906e1c5b94e9c813964dd03eed6e215dfa3585f021effa39f90e63b5582bec7ef640c62c16a60b4756eaeca8af715e26059e990f43cfbb3c394c0f8cb65fb1e30577ab005d86cc5c4e37816f3d4342150b2f9354ef93a78e5b6fa5af82f1d790236b1338c2a17c4c07bff31c1412908e088e34f771d2f70351d74a9d437df39a2ef24a3817cfe8a47cde21e712673f96bff6eebfa4ac8232f02df6a8947dc1b8693265070a2b483b009f703e4fa21503ed9004ab1976ff0b53a59f3d35a224bed958222dd1547d9033140b89aaf1a9b9dbc647f430bc16205dc95c3da2aa92bc7aaefdd44cbeb8a816cf6cf7e5b70302a4cfad32ccd1a17d2886b54be3764fe51f7dc474577a05a0e1fc9b42e4a4ebf099dc3236f29693281f86d235f3e8ab7ac3e0f90627f562039ee8fad2efb61de46bec112e0c3888f104fdfe874c452107f50641ddfb3e0c0bf19d1df930f3f5403f4ddbb108f020dbf6f65ba7dd8012420204d7a3d219dba43e86ecd6f92a70d56b4c86c2af9996c63440d4951b4250be6388204bf6d5ef3f8019cd1fb026e0fac838fd7fc711f9836d497b51db6e5b23a941a2c17c5410c48fc4ec3163221f68e179f1f0f06eb5895faad4fe3b86101b2787840f83af019531938081732b3f25000650cfac84ec9f247272be7ab1e638742d22c06c800dc5d7b2f9a0ceaa5e7c8be1a33e88a3c88c04710be1727e6c31797f5d285edfc4ed81d7137db70d87c4e8674b85463d3a9e9a49ac2ceae91ad8e3cd66453d2880cfcd10b68127690d74077944711e12365c98e93f89f828dfd8a67e643b194f903e6d31bcd9bb3c52f10035a7c110bd9a734189556f7485bfb9f6729ec1aa57b21ca27beabee972ec3a362aa8ffe083ec6acafdf42631a2e96f5d9054b8077db6737dcaa9be396c17be4a9ebd1216c73abadc9e6687cc455e27298c269e0b20aea5b3a68c21528e537304614a1bca7b809cac490f4cc5502a0be40eac9446122ff4304c46c25090b5de98fa0ced5618bf73ac3b798738b70179b44e0cd90701ca9dde32657c7a59f5bfba014d02489fc5ebeadd8eefafa111e8dcb4b2eecec2d405c87354347ff93b78e045cd8256986cbb8166beac123a380ae2d827e28a356af9049d70fd3ff5412da562f13a439c0f3400e76e9ed4766b69b81b5eccfad83d7f4109e9072d5dacb6264925f36e130e214fea607f32662dd5feaa13b9b836486cf2bec673dee2059a68603f14e5060098e71c9cf7905f924c2af8edf4fe96c24149e7605449ea5ac3c9c07f6d2eb1f6424827e7c5212c0fdde803cb31d5db30d810488877e8f393682e88d0648246d707790c28662827d1a58de349ef043856997e6e607584008b45bcf20966c7688931d856525e0288f19fb1808d4842c7402982476eabfdfa60c121eae0aec5165fde6a76d0cc47fcd048798a2805e7ab1fd16be3218e623eac972797cebc7f88d0993aef2ba0df841897be2f80cdadff4918e3a628c07da49b06b202ec839867d7e6767302aafecb11b43b39800e84376bd8151c4aadc37dae5affeb749996074f4e1fae887f162f118510016187f20a3369530bdfd2050b000ecf1f6963795364a8fdfe258e6bc9f79dc7b2d720ce0c9907b0de69a537d43d6ac631571c69204126d930e239c2a32d3eafd5f623cc11a70a86527f12581b5c540d7c1130d87a0afdb3a50269dc946218ba5240c40970768fb0d2a30f61d8cd129dbbf9d240107d8bc746d1c69e9ce8ef0c1c582fcc673c8c3defe0e8cda91db26e0a8ae7949082f68dca9ff8cafd61d7c88b00afefc4a7f7c330c1549c4351be56fbaad1b11efe6ccfd3f3a1756d83e95f85f01932b7dd586a7d69a5ee932727fb3ddc6fbb23268d06fa93c6b7a103cad01a106875340eaaf2bcd76612c01b74a51cdb516fda468df54088e580c42f51c930e89fc431f5db97b2db56b2a398df60c5dfa2adcc1ec935fb396f64c9e1f794d179a12beda7e6fd039b8b2b49f103093022546621a558ee02dc06ef8ef581cb1bf2da113724a64d0211196c4382d06662a359a57b2bd436c84895cc7e0b7e9bc1501fa97c2a110cb6f69ff33d017ce4ccd452774b467b63f8f613e4d865791ffe2d7f6d5eb3a2219dc9a1dd536240277fd26be20a9d0a0f7f77bcc0b57fce7f1ef24ea1d5419e6ff423f7b0e651a1737b3d50479eb9f5bf746fdb8cf4872a6c09f60560d5bbd1e83fb4b2b2175326c26f63b6b9f4a9c10e526dca98242324c8cd371667f506bb2e0309e6364f82920996cbf4371152d53d0335b0cca4500db3334f6abe9a510e37e37444b083eaa0c998fcf8f78401f5f893e4d97bf709a17341365100e52c948ae6b823fbd30df9f10e4ff5c0337e3fe9de346b27ddf780b8149476a2f302aca49723bf3f1b1ed4e972d056fb5d331fb7d754f383c3bdc703ffbe6d0ae7f76ceabec949c8b7152dd29b05bf48a82ac6248e0fa4b781fcb277cdd81342762ac8227f94bdff29c69d566a41f68882689f59c283edd28dc28e56e61f4edd641dfec7af0b958df1cb9565754ae9da389c5f89d5264d942a50f4f8227218db0250b2736270f5773df39ff2bdaccebd60286cb43ae2066d9eda8a98945108c8782518027f98e92dd103d8ea37f0a1d6baedbb4af1211fecf84e2d758c7558ca7f0df8dca064b1512e4dbf979e76f75388b93e7b90b2f9acf9246deb094300552f7e1327480f7dbff8cdcff0f0d9a967c1145c6195da5ec658d72813b94b4ae912ce4678b4e18cff95252f91dfce12109368e3c6860020ac7175c0ed47c9013722fbef2377a3a9311b00362161f6bc10f3259000e1d52b0e91005e43efeb90cbc55dd98241cc3d394dc807ad57cafd8956bd60b08bbf8175f35ddfebf8b3f8a1b5563d2ac19f2b8af39e163daaa4c94ef103c34e2af42fb6465849b06803f16e1f330c00982a4bfd37c1658e2ecd34e6a26f33da84b8f67e0cf2ab5005352115dc778475159d129badebe07cad4c7e2e265a7ee57b33b01cbe14110b4265eeda2798a7a6c18bbf7289645a3889aa3798067d0da48f75dae67aa8fd2bd8fe093efa8ad52e405a9586f3d36cff53dc6fd75b23d944c77740a339ea2de43549aca914d30c03c68276803d01d698874273257ee958a07e03cbee3ac489beebc363fd3980d29a027a5bcf9b8a1a7346733fe41c4d233300a62d334bb62ce6c2ff020ee8479256c1060454cfa8b29c162c629246f0becf8b852d6c904d07fcf115dfbf51a34a7c2780717d7947a7fdd017b946154b67b7f8c9215f75a67065aad6f47c4546e0e11f943005b54e9700ca3afce8250eee315f7650f2d1b59fbc62fcf0f64a73cbb89d2f9f86a56c564a49cfda6e80eac467ab8f0577102a298b2422e3e7b522ffcc12bc01320e2839517a99502bc73b2d4a532cb98387c6e4723d41a5496e27e508b35f71b2acc2e29bbaa72dfc9634f1ed112ba17206e9e52c99ed4a987fac47e49d1534224a7cd25e05cd5d279908ed91e23b1cdb8fc1b1fcd24ca2be7e1b6cf0139abb49489647cf2992bddc6433b0f9e2d72976d4d4e1fae4b039ba7d7d0e9fe56423f5aeea860ce5e9fa5837845c81b1dc1c9ed71b35a6080209b571efc3fc1450d2bcb3f4ebd94a5d4dce94e061de3d4013e08593d553a66886d748b68bd76adde2d91b2a152b536b28c3480a0eb618ce2b7ccd81ea8fc0661dcb7765296418e84b88eeecf2a32d7377b0cdcd33c1846f0d63804616de2bccc2b271791a0cd8250e4c4a54a01d64f85d95a8b15f7c1ab7fd6db0d70c613b0ee35b03410090d64436a8eb1a27b54c3e504632a369cccdfe6513a310f95c37150dae4e585355b209b06ac11794e992d9db50e1c85fe67351ab5e61711bd04a3cc94ed4a2d3c3a0a76404acddd754bfd07b6bead7f9d8e3970ad8a1ad283fdbe0c6ee9d64ef1f5f950d936ce7135b8013e8a5ef854dca11b7c984d9da15547820604df6d0e30b896da0ab8329306220a4d095c610566196961f840733f872dec575ae58c11cf507248d3a5a017bef3c939bd05b789a41fa6d0ee0e41b72e62aedefd033cceae2e13404eaf2f3ba109c6cdb10cfa8b4e6a78ac3ee7978a273c999bca8a58930f4914044ba6605638ef5dff33b6b4b1fc7cd76ce502060affcb5232760f8aecf01825c14e3d1c0332b98a01747965b8e62c1cba3a865754aeeffc1a3fe38683a0ae89f7320b1ba314f1bc5dc2b47b094ba9242e7473245e6feb8e5fa63699f320c755e4b81f8fdc22d277d62d50bf1ac0a33047b7ef43c9eaad8376e3049b7a772cd5a21fa3a1358efa46857699cdf4e26ca3541f8a508b9f4baead07e9b8522081461f3a965547dbb7a43cd53f804419bb9ecccd7e0be09f69b07d320d52db53be1be2f6b4dc4ff8b7665681e9ba4cc8b6ac989bac9002a15913d0600e7100cd086494fb0d44da52a13627adb6089d8634288b08e9843ce090e79c37a286d9facda1126adc9bcac24faf62650f793407c36bb71a4e26526c7c84521aef3a7c702773ec2e4d9648a2269d86002a11325dd8eebabd321a4f6478cb670b8fc5b1ec5346b58e57915a776dd1830854a81f2716b089a336d3c4c9bde6337c9ebb94f269d9990028c04fb12ca59c2eb490470e33534d8efb250b518d7e2b23d515a716905e8e5200343adb21ee504195f282c913534a76452a49c76b8f5c33a8a174f5052dc3db943565e6fccbc36e7951a1063c8410a454b7fad8e54a021340062d2fdf94981dd6d88995014a11a7dbe244b401ff88d6f780ae1c0945d4fd88c2c3426296bc2c80");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSphincsDeterministicSigSHA2()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.sha2_128f_robust, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initSign(kp.getPrivate());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        byte[] expected = Hex.decode("e8a1883716841afecbd6f9bd8648bbf86ab3badcb227b624633d51913eb337e07b68834818c993532f90581ff8e26477449fc5f0fb37c9d8462bee7d3f5825316afbd4c9a2a266d71d7f8ba4db064c665e02e7aa0d1ba9bac5d0ac0934db69fa09fc85234a701887cfc0af912c7b5d3186c0489e593fff2e9b5c79a0a77ac312aac4049d29ad57db8e86cec1c1264e819c5083bd03b4ac44b94be97756e2e4b491947a2103b371c1b54940bba71cbb7f9bbcc8eb90dac25795d1148fdbdc3cacef7945bf9744c966cb73cde15b98721440d2fce6294e77c39bb2cc37738bb2c2ec45a8d64a7fdda31c2a5f38e9cf17afe942470f1227e05b907ada0564ff9cc0e1154b1459f4a4b21485d901582c2cabd443635262c6a899e774e27d7428d980c77e2d42c15bf9f45b702462dce170042b696598fa8a850beed7517f717cb48fc98c8634296e3b8572284717fa5248eaca46c8b20670c31347b919d6569d351e4ba30595a5adbf887c8e971aed2dcceb4593ad18db1e5f9226ae82366e5c99c44e22ea292912d00aa6c53670bf6ed0e969c56a95015b8c5e0641885b4ceaf45bd2d90d5b93f5b0f63a8798a572935e2300319aa40e6435441b611149750638e3894e66e7c3ffc6a4f1cb37456a7c82b05e2b6d16f8365f05391f25539b835159ba9b775e85abda82d16d6b7b626f76bd2e98cb31b82ba8f18f0309c41677c2b4f5e822f255dffe17d21e7ecd421cecdb7e6a3f88e4d76fa0eeb3d7e9677c0c983223d029a025a147399ce72a13572edb7d2689b361993a06492df19fc5391a1e6e89d4d81cb5c3eaf1396941f9a51b8897cdf725ae8669f2b4b9435277ba13899a8f1805b77fddf5bd6b2d6dddf02a185d10f3196c571ab246bb8e3e1fc97b0b0b4e1c3e2186f6839b615c210613c4c3c7fd922d1907fedf6631bf3d1ca99914ad5c9fd34ca51ae4093e2a925c6a967b2c2e8c97fdf73d8dc3c6fb36ae587e50e0b31455f618811162c30ecbe1e2528d325a8c75afb13cceff548863c535bb6f72779fc150b74d33b4f98f7dca144fa554318cf48863fdaf16c73ab14e5c00580ff227803b1c8c383713bffb6144ae7b02f0cc1113fe2f57b72b93edc1e0c363ad4745e5a96bc61b2ebfe5fe1fe6008e734fa9382c0b818834e22611433ca213cf090c5af84a318cdfd038d8cf6936479d5b35dacc30be7b92e13920c0f80e5a6365ffa3b0c35ee637a4e861817b10b6c6b8f6532124c45289ddd027365e86e76b57ac42b6c15abff1b0426d1456299f9585b16aa0301d333837e751db28c0e3ef942d577655b70219353954384b649dbb4cfd8754d80250fe9ed859ab8d51e6c663ab32bc6c5972620214f3e08b3275829e1e97a19e2795ee39a43e56c1adab144951ef5b1cc1512eb250625d7bc18165a20e588f03075a524c0cac05c5da810632680e05516815c5b32262eb5b3b54851477edd61ce14d3238c3d02f4518d809887a49d148e84cdf7e50e0c06d82b41e152a5151a576c69fbc812c327d440b41edb75c02ab444ebc7da11143e440cfbda9c6c7916264b95692029e4c1bcbe56c55bcb2af6530131147de4a1b384b46179bce044dc104a3131ade59e4a1556e665d6ae0ba1bfcb433215d6b9d5be7b023045b0b49490685808b1a545577abc9abfd069aacd33863c2f5d0daf41b4c5af5224803f248356ca7c1269315c1bc4cf8256cda2e1dd2b1f227b7032ac29acf80732120ea3f9aa07945b602810e8aeafccea49d32e5050f248f72f3fc839962ae0e1443b46b586fbb48a2aae82cca180d580312f918ed208a2b6a493cd63b881a75e321a5622bf47314877bcdc9474019b5c64152e003d857b9eac87b3ea6c8f378592078326a4cb16d66caae17694b306ec4965f85a064175763ac9d4b457be3609188ccbeea07087f5051c66b5ca51fd88fb91a1dcc3f93ebb7840645283595fd3c4148bd62e8dcf0c5da4b89492222106228717ec8b473f7505defcf6da41c8e31965c76a067604da9f031f0b34235d7ef587748ba03cac0f104ebd1d29a44e0ac96c85359550a115aed8a8f15536032b6fbf4ac8239eb94391b2f66d7f001114457a938e5877f0eae1ad36ff6a853d96ebd8d5e44391e83a940fe538dfe2caaebcf7b6110cf4e51617f3619480c3396d7c9d2af597e113acdd794cf81de24a21285f4ca9bf56df99e02587bf89674e7db2a1a06cbc217940fda6248befcb93a3f947234e59ab6b03333932c015dba3c88092f362d0baac5c5b9f2d9d5a829dd3ad4644e0cde89d4d8df4d547187d66179f7b350112c4c004e6afc97fc97793530be06c13737386ba92b13cce0c0b6cb6b0aa0d82000d674d1998f05b271643ba85f7da6304dbb6f530d2c80c40c3e2f925b87d32603e377b3a9ac486e0f0186c191f4648fbb8e230f192185498e3e09e82d321a9a6058c553419e21c3ddbf147c2ed88f99398a7eba4db3a7ea39b45693285c4d6d6c8a1eb8e7bc0ed937838afd59d003d69623f6cc6740f2a7b1808073fc7638960d649256026d9b714d903719ac7959405eed2a22e4a9d72e33ab6f0aa5d07be4783b4ddf36af1b4d4c78585cfce80738b9c1225660f5e16d9de5c9ac285d24db80c9680525d419b626435fafebbb683c9b36bdc1cfc185cfe87b6ae93a14e3d63db6688f300154f288484c07c97d82f438fb9281afe6254170ea6d8037108d8984e88872f1c9072eaa46ed6ba426282ddf6365f010323e176e11309a3d80be22f8aba5cf93dbff8658665a9d2e3b428e05218d9da73aa0324f9500732920cb278bce651e21816c61376d1cf6d2899f02423b33be6a8217c217dc42b1f97abf8f63ebfc367b4fbf0f158a32cb2aac06616446a9773f6501692cbbab803074b5c026cb3b8ab7f48d6e5818e668198cc958b8acfd6469e8b835aca0e5bfa5a8f301ffdea73c8693f6c656cfa411e7efab0842da13aa7132db26176c792fd1a99c79551ab99482be3674bd2e37fcd8e0701f2a9cc801b56e717c8186cae04287fc741296e97c5563c4b64e7d36b76cfb41ff3ef32c5c88a4dc09ff91a215d157fcae725f7da8801e72086e3f063529eac6a11d4845c1eb0bd5845801cf9cc35deb27d7bdbb67055f641b9f4bfaacc0af6124853cee6cc3a858c1b102fde6da1d245390d6a6db8492b1142fc09b90d8c985ddd2a82e9e79355a070eccdcf125ba45a2543d473cab41cd9ec464b77fd57c54dd5b346f954b1c2acd37841f29f9b7dfa767fd029bddfbd0cd3aa285540a3943c6d1018f4cf87fd7c17fbbc65016d5668d2b90e01f3176218160ef5241caaf3bbd747c81da560d1debe3dc258197740839f93ca6eb41e7e635340e9de07aac1b24c5f48182d0bdee3672097d2ae48960224038c8fd710845d0927f647dbe09062c586842d31e1018950a3e16ea5d209402367badae58d2344d169cdc05f5a47f86903d18902ef3bed7d3deea961bc2e8e7019d77005ff88be637ed0977354b26ca98a7c0dd436af45341626540e050d7f4f03b703f254e32bd9a3d2f93997052732773c2274cd1a26da956105c5fa59dbfb002efbc28d3cca08f91f0fa76289a1f68decc6f943cad337f710e26e8287ced6a35b3c4a5b2598162fe2412cc2d44b49948f383403c23ec22c585e95f91063202da0755205bb592fbd345e10bf1b545187a7c14aa88106bfc37bc05dafa17f0e2bb8edc2179b3093bb1cd955beb621d2e222b39af3cc1ed26c7067012b4fdea539c983e1481b70dea56506a3ad912257cd7cd58da4cacfd4370a0dd292c319f23ee3ead9695bfe91c7e83bd846bc186b1703061a9d4a69eb961ba06415d4dfaf2cfe839337a6efa0e6b4f4a23c700f678e517a64e8a0c1eb28c6044440f203d9eac89c8b7d406a076bcabdce36195119001022e640155df8ef46241ea50204df095b96deeb70c2306cea56794e9729b3fe27e114a95344ad4d033175decb92e0ac3a88a16e5ba32f8c94853764fc7aeb16591cd3cdeb84b24ef6827a341355e7efe0ef360991a20e6ae77a04d66bee1da160f14ceeadabb7844e3baec99a057202d80f41c01c6f59d6affe7497b137f93e377e3b9f6df995df70480098c46a85e5b9d9b3fb7d4b7c6f4c72e1ea8fc442f92d4d74b41ce026aa5ecfac54ca2b4f45995799330082e0b558f18c5e31e698c67f2e82dca0ed3540f8493f8176b9163633481d4a444ce792b1b5b7c1f390853aad64979678de457086d7b7a0c0230ee0d0c269322812d5e7dc8e6e1e03dc0c977e81a6ac37b328af654ab070c6b073e3d0194046e9e91898e8459b90faba6e0c5a14a764d919db650c798aaf27ef1ef87a62b3b5d0b69a5abd7ea8e12e19a74754deadbcd82867ee271340c0687e7091091585e1163da7ac9655c91a62da7850478d2283fb6946306834f2e56025d863044b564818de7b43a7d895bc3b260f4d8c55fdcb09d8d01d11631e7409e3dffa027be768340e5a1a71c518396906b1ae32b44b08f6c0b54ca53c7e73375713656815e503a799205ef9b6753d177794c753ec2a067421a13272d09131fe37d212c19790d707c327146823e7442b56bca450f3de89888637e0dc249c2e42c6d6d47a6a49a27dad3aa5b543a0130d7d34f6310bbf8aca6e514be50e2cadc80a7133545d56bfe06a017191e5dd5ed598ba52bee9752896c65fcd4bcb9de79f7a89d781dd47601df7445e23104f2d7f9341d6c1e833247b1f5b56721255d2616e6edf75aee159735f15a70a170dcced4f0d029800b6462fe50379eec7119530650b4606ddd7721e568e52a934ea14565168c45cc0b4e540149badcdc1f70e3079f2adfc8ffa44333c88c5e875e64377780a23573a6f009d8f8d8bd3a2ec814f9a5636f19dedd93b0ab1f70a4b6666520d7b060925c95c2725ee065f52fd09b2f3b2b89201de0174ec755680cbba3e5828298a054bcdefa112aa739c554f847069ec6f4bc30c099c67eb930a68d20a01e5c68d12b9f1b1f3c557fc9ddbe6083aaa884880c95721c85ab22cbb5980bba49c708edeac69a95f7e0e70c9a75fe011411a1ee730f2f6699ae74708608ce6f33435efa0b31379f6c8bc2494dbe7145eb70f6d4d46f8d7827071c49d55c487f9fbfe1a56a7db761cf3d314205a18866b872aa8b9f4b68a930dca64e8fc294b6d59eefe25cfc1008689c78a1e90bca877ce9f46aa05f81e66a415092ef9bafff8d4732b12976b925bd83439e547e3df349eaac385d674bb2672e23290e5db0784ebabb24bed7831e9965c2db3dc8db4ca4c3525b3b132439fd0de7fd1480e2e697c2165e1a27b646898c1af610276c6f58fbc84104a345783be38749ae3f968c980e368b6c7943fcd5a3fdff44f4a44ee55cfd7f94d0eac235dad9296e979f32d5ee4fd624aaca794bf5cc30584e505382b852b880f6aff7da68d4c7970dab6d5510036bb453a7462d7cef59fa78d03de0ba69b266685dc2f17ce8e8a6c23e465175b352c977eacd5fc611d55a03dbb46a831e5016ea28329373d40cba6414193641f75e27a5099676670634008678c3b5d1f14e688a1196b08e4dd855611e56fb74146876ee12b6d7992dc34bfaf68462322e0f169e61b127c00b9c8817cdb59bc675387f671e913d64662128134932a50d8cb6f49a13646fcb10e2c3f1c8c517c5296d1285660549d1bc0ade7c03354749ea811002a9cf526100e264a6f9506c563211e56a811d8ee8eb8e2e917512d9bd38c0c1f51c6968cdb10b9d526d19f4762636bfd9353f904cee43d28b31f6a65266f46e0af9e7882aeed238450a985b493bcaceaf8eef545c93eb6b7a264dc278fd621c338f7dceddd29f68c20625619374410db7d45563e2d90341c475a5df5a5f8dccf3c648072e205adba8327eb36b9d2f0e7dc5ae59933063ef105538974bd47f11379566342c07461f6fce54bd2ddae8004824e93eb63cbe950663d88c31b9cf20e4abfdc1892405b4879cb32ce9c6eee7f93da5e7955d4c04b04cd13bb4ff3f13ee1ced444b80c92bd18d8c122f43020bb423a15142932bf522d9df402a29087bca975a852865ae27a9989a5921ad4345cb4a64f7e9f6aedb0217604a11b3eab8b4adaf2b9f527fc108b3a6d94bf6d0ecc63a237a70489041d1d499316396d67b5b8c73f6e6b91d0a6af32914fbfd860087ef4d14ca4553cea4781cb9b075e47a9fac71c38779892c87a21ebd942a596be33fa3f8473e869d99213782866fe8ad4a79d4d2dcee9abdd53de125a179af9bda9a8b8fa9092ea6ef17b6260da9099ffb1cda671fcc364ad5e40bb4028115be8833c9c6ee381e64c20d1ef056cb5132a04dbebadf2e62f8c545808f685f8f08e817558f27ac120970d6fb1250ae469d33f181ce62aa6a150fec671bc669427151da2e8de1f010c572a000172ca2a140ffd253a48c612c413eac55e9087817b42a468e929e116f4e33a63df26934e2478e806a583493c985f75c4edac0280317bfdb572f1ae1452aa26f3076e7e48fc91a253d689dfa76bb46b199abbfd6c5533da987747dbe90a4c9a8ca664661d8f09df9a2b6648e2b7185f459084f35a3d56f773da2bfc70b1d7ab0ddea709362afb0435c6e6f6a58d0cc42da9a884d76123b6df031accef92a77b67a906abe90abd54ffd358bd9aa977f926a71bc46a5d9b13ee0e4b761771ca5538601cbc7204463f3bc3821e06738acd83cbaf7571abbf032e9607ab7be96baee4ba563932f172ddee5d6adfa4c01b21439e8fa80101847ae4cf5ba289d46fd65545a45fb7f4186e02cf9a0aa2841bacd3c463d6f23ac88514c9039987671fdb263621b4ce663c7838dea4568905a5f1fa3ee4d82f222579ce278e145785c5403bcb37825d3f787ed3f4a657c7d06a77c31afdd33f4042d6baffa3898da308a9a2f367203bf5e6afa82a6d5c428cd8b8bfbf98a505cdd24282867d89d7dcc7ff7f56cfbfe6ed07ebb3fa36ce68ff1cbd2141a656a7e62ddd90e5fe72308c5a2a3a5f198bed49e4b7d373ae4920ea0ba52b3c9d8bd9fa45a655bbad9ebfc64f06a759a79d97f0693f73d25700a7aa7dad283b88c9d62d07951642561911f11e1c7bd760c9a021cbab298b0bddbccf828a2d203a10e36b7dc7d5f40df67c226a9a423f8e42a62a3e91b3ce9524e0bf9d2d18e07e1d0fcfb8c67693168871de6b5e683c0dcf46e95ce63b5887d2538f76078121a5cf124f2f0c06226387fe22be207b8b966b59f12a702bfbd6b00ba9b6d9ce2beec702e262af32ecdbf54811850c51ce03544087d7b0a292a87e0ae406e772bcfb02c84c513e05836ce62116a2e21920bd219d49d0d888156577204b6222e1b017a9bf5f6d57f43011ec2631a6323ee0238e89d0cb2b20b504c485f8a2a001e79d3ef7f56b71e8fd30add6013dddd984a2b5ceed885afd9b59bc639fb2dbc5903acb55bb2612e4bb7606f5431d864a12770f0cda1ab87a9323a40a8db68214aad3a00e3fcbf12d2327e33c658f629edb36355de41e91bc9ab3f4ae43dc43c7f457a28f51eb1e27a34db532a4a869242848dc23399572f4a02d07a52c58e8829d1c1a6e2cd123707240e1abf62f737ece64cfca027b31ff67d9dd567d4ca309f18a91d27a40fd2a4c1bb9297ac329222675d533d048d27909acd0d562589c137d6c0b4534ed1488eebc2e823eaecc1de95f120d2fa5292257c6c0e00b4352fe3da2880d08b7e4594770d2d0c8c5f2ffbc349b7555739226e5fc3c1f1e4effe5072f1fd8a6eb1bedfa334dfd7c6bed3580f5209773d7c1c133d26b758b7132436810f27f497b7470ea735fec626eb95b9d301ce012c8f61aa4db918c38baf9d52c67c0b2add59693bfed42a4e0263a7edcf473a481ee870260f3e8b22a42a820be4b65e797b801a86e2693a3d9364f687aff0a7177a6a3d35c535239585688255a2e378de152b88133be4a0524ad6ab72b539006e21f67cbe460ac56fb696174b87cff050b2c577b59c0c4b1677e5e325ea0b7d89d68a2438d9a2dcdfd898b05327bc8a8fb9c7df586c7659ed64de3032bce462832304726aa0f842cc12a4872172bbb364b5cb7e5d24eeb2d332d15bfafa591c9616363d945f14ff46c6b98ccbdc8e949a5647312fee2b8fdcf3ecbff2d7e259ef14d5beaa0cafdc81d8434afa394ca66769d230811330f7b1f68b6be89ac987a45904fc4e853134d5d3a6a140fb56a5e8decc3c37d98cfe3a9b43928f2e01efe9518a6bb7749dca1d7ae8089ee2e3861151c260c5a484e2f563c518bdffe45b2488cdd8e9e965aeab01bf894192b5987f1e96e18f75266e21e72c5a728ed2995a1605b33e8ecb21a9d56d25938730d6936c701a49a155eecb39075e4da05849c67dae2f2ad40962837ccd03743cc331e1b09dbba32ccffd77895201999664638a2b035fb346d2a65b3236253874cf6fd250666f68fa517328abf9014dc8545736eefbe2649140510f9e669b2e28bed80f2618898bd2eeffa0fb5e7f962f685d42a7f694255a33335842dd5f7f48969252a35edf0f8e6920ae85fd2836f89d358c3e451ef5c843c071230a2fe30ec1efac1e58fb506267a50043fe6b9b0aedaae9208520d7285bffa2857d0c7d276e9b7523a1c22b8889c5295b5a539387d6738b996964071e25841edee21f1884ef73fe4c1fafa393dbeb0a6bcb56598762c554ac650797c90fccf5973fca168c3a9ccf0570a791c80be4840039083318589138f566ed5a0222e4af8ff3a3569e4dd5914644208b2289e790f15e5b4c3daf9d4033b4e1c77c878fee8493e5b0f6f4a4ff5657922c0642a7fef854e5a1620af30d8804abc4315cffb8e271991353556fd2e957c235e028c2afbf0a2c35a998cfe3c87f1e9bf0da9bfa73a67e5a6f3ab73c9ffd554c82fe52b742a25587d43fe6675915f2e509a7f0c6566196f4c5aae24bd495579026328a85f668f685466fdf7f76a8becd25b2cbbac3efb8306b2691451414407ee41fa1471055a2ab02f5ec99b2c612d0d1cd16f1af866e773d6aec53ed2dda0fb6bb140b766c0b3a0f8e6012b7d67554e7c7a1876f51d0cffbee1fc1a11d46257bfca462c7a9c17a4f872476b9aebe991846fcd10c431beba46f02cb0376a632c4b6e8b10cae1eff3d96224886c1d885a8c46d9dc80e6a5edcde5d436b902cb0565be77baad995411199151f5ea61ac1d7ca5014fc2ebc01a8cb9d1e7662dd93f253eee23f474bf3a25285c4e992a0f77e7c707a412d50e5a04f49f1069a9b810f2ddc9ec9f468c389279b75bddc6beaeaacee970c768a05e1ca667a796cc4a5acf756401959738079b0578a61a80c1329ab59bdd2bc62fa98178b3acb2972d47539d7b97bdae13a81be76eac592537d096902a248eddcc8200030df3f9a2963ae7c8a3a86e83595940810a619b063d9bc6fc0cb75035e988acac64480f5a1a31a787855d8a83013919a793d4de679a6810208aae6835ba9aae843e6cde97ec57296398ec3c128891f3c7e44f3fe0c9779350f66f55ec3be94f9eed53dc6ebfbe53ed427cc44089a70100e605f554f9410bbbf77adbad858ce214f06ab334228b8f894fb7a9b2e3b4b53baa67fd4311fb910c424cdc486e6739cd432a711f570699a903c52a7071c2948a5c6c9d125abadccd242e24c2871e83d7c048dd2da6a476466a9ec31a35a652c06be1eaea5b6820e87f880d9b2faf5c2a7e60355e4a941e1b748fba735d0e75dfec06c6a9f2e57f12171ec9d6c69c0fbe3c6808324175ab324efaba125a22cecb55d7be793e6799d6a8c2a64774ecf894b09ee626146d46ee5b6875e74459751e16b62a4feabc675d887910cea345bdd470fca4229237d4ff79b7673a974bac5da0cd2f3df6ecd0c21ea039acb0cfc74472a7a97a2116d3250f183d0e427228a9602fe6d39497b02713c61e478b5c1dc68aa0d1e0294d7a5bd9bf4b8182d2cbaa1b9455c2cd2ee1120c83166d6f2dddf1311f40168fbad45b1c7afab59b95077540e64b638c159dda711a35e0bcfbcdc89f8ee8da56d7dfa2e23f39e8dfca2033783a3380c031deef512177f7128400ca8f49d8cdcac9ee38a5f86b8ff90664418509fee67e383bfbb478d7434ff7a6f50f6b4a279be9ab33b7270658f129e4f56526f32b38887eeeb13e2b068bca0914e730397ce5003d181f777b45744bc43fd05141178878e2f2705017b4616d23ea244d54aadc74c4d8ef3cbca173964a50521b13cf235c4348930f1c7d17552bf9f89c988f977ed6078fbda9f23d81e117404fac83961b7d23a91c7de2a5aeaeedc8ebaee2f0f76d9327e81a1f23fddc05cc577e4c0dbfed207bea589963c00c96ad79f2360d470e3304ad86d203e1c24738973b46bf04609f1f744dd1975c0c7f7f4e7a337bffbe7c9e83fba1c69c6e18287f3afa2d3996ffc1bd5193ce2b52444fdcdb0b19f701297d88d0fa29962cec5d2ef399feafe95db1f5e8c3c645ae63750de0406d519710dbeaaeef4139aa1b9687f4cf3ff77cf42acc00833bded8e853cfe5ffb8a369800b227fdeaaf6f54c182aa21d1398b29016cc7d468424beef0f5babde8ec7b1b7259b0fa178d98a5e2e2a6f100fc9b2dcc4ee5ea49b240bac283c9e4657eaee6a3f266b7f091d30e96666c14f1285a8671d02656a3e5583d4a4850da032e27bc13845a807b36a974593b1d232bc7742f3f20d1111781746deb4ea6ac95653a1acdf4f649bc060044d3224147133b44bd88fb13caebc41b36f7e48ec97b21e405ec941b270960837be1d49179664567d1ee2342cef5f9e4a559c7b27aa5aeb094a60845308aaa9c2afe5fd4cb808a44e4b6211111a69b40862e530247320863b7fd37fa77e69f05e05a8c43b51d3dbbaf3c715e5c348abfcfc5673f8c21a8126c762325ae3cffae51ffd43cee880f480006b7ef63e3a9ac33e6389466ef1a0b0e67e47537db6bf0f4950f735df6cd81ac960084df5f17d827ab400c074f8fc09bc5353bdd8cd17c6dec09842e7fdfe283f7f33133b33b704da89184ac05b9f98f0b64a5a437647107438cbacb161b6ec97814f56928e800ae519efd7129bfbcbcd4b305a9c703ec4c2b7fc685030e741f951e182da0e0297f99b28a1adec735e4a8b571e79035b78513b6ec12d815323fda7ed61353c52d490186450359c7fda3b45258bf276ee655cebb8bb23b20067bb914cfa50510832e93be450dfb9b7938d3e9888632938ba8d52760169055359373a558a7e2db3e3f7d31476c638a263c48b02f73131c737be93f29b9d9612b6d91434a26e6bce2b536a16d866985ad835a995781cb72680b8a5ab806da807bc77b9ab0f5cc39e845e2be7599db544dccf61c214b998469e8e7e568db4d171b66eddcecfcbc74535753a1b430c91c64e4ef97fbb70bc2468173d0362940a1379d90b358806eb49c2632398b2572b3d821cb12c0fc32c68106d6357b26ea2cce6c6fa8e1a17bda0fa64820c450752483cd066900f36ecbfc34b100799756296d7e46e48c5c48d38cdf333b98a8c7aa1adc2b02b58a0189f2cd046a18d1778192d98cd9510b40fb35350361fc4c3e917ac19c372f196e52c976c083ed500b4238f636fe21b9f3c362bd2556b16e45f67de52aa2e8f08d92bc19fd18a0030591df154df34ef121eac4ab0cba5b5fe8920c4c3f3a63a20f439ea9dcda4ec0d7601fe8849aff4f5d4d5552cab4c73b34d41543551fe1008032d101fe1d94ab4943256471f4bd06eff1f9593afab9fa8cd534d88258936cc593785464f4546b268f6adfd878911497d035a60a0e6c68b5884d76bb4898ad59c41160321b83d40a364cb427699c201ad78852a22eaaef3d5ceaf9de365018b271e16abf0ff5819345ed4764b70b88decf41c15dd243d81cc599a2fef2a3befb2949f2ab244fbcd412432ad3600eb5d92d116ba618f8730a477debcb3280d8b1dc04bed8b360ec7bb47b9cae89d25e702db37c5b583fd72c3f0c08a1495f75f15982a9931fca16b5b1ef1868c50a855116e6e0f49495ef82705f3a3c8d834d1725f0f0506060c2cc37e148f78f020fc701424fe46a5159e3a73dc834433d244568bbae114f475e5e60c13f47e9e14db1d21d451d2c5f39c39af0b60651d059a899af0181ba0b4c7fd5a7e1416adfb9f5381b24ce947b7d09a27a264acf7f0fa28d9db6f6f277d86e94ed96a4a53cbd3a7fe099d7177c2d6ec783314e08947f6811d60f069a1e65663b93f9aba00dd7de119c550181262340a88b316c191cff1c7b43d936a466c0226a5968c2e84ca61faf9a32cb3170fb8d105d25b3952395426d28531797154875af2cd089f7505dfa742c83a9fd15ea57427767df5db894e58f7e026eb4d126067eca69c7c2440d9e12486c63957013961c24359f94f5c1dc239bf532998ca339b3f0053961fa7b71c3c2a614d4b8a821b5e1a5544c4d079e71a43a7965c34e981a1c5460b25b6831979883e48f76c7ed34c844406cf5268936c01c3faf13a235b72444b9d7a701fa9a495231fcd8b8ed89ff2993e7a0241f8ff77e71badc7f0c471024a240f4824da0ace63db199ded2e6f3953c43cec3f5d60394f546eeac40331aa3f466af470311bff164fc90b00995228cda7e239b354a10269904304436ffc6f42c17e9b9ffe9a946c205fc0add8103e12e342b4542062ca0083c286a0be8ad469885fa7171c5526e2baa153c8cb43d33e9b1db7c635827ecd26041aa632829acbe53c38f63462e4d7a308f299efd555294be0894ecebd3a11d4242e1aef59cf77768197b77282aa0dd81d9085f87daf6bba680e40aa252629e2668d87eaf38be0e5399c95eccf3af5ef5b6b9d9da27251b8375343aba5406c6ae8f78d2311828bac89fad2291433cd2ee74ffb81fee1a3170ed32305ee77b1ecd22c7dc6b7b5b400d42917275058a2be78bcd1d79a661aee6ade1ce17fb1cbdbafbe2dffd3884dd87e14e36fd4a27a5c64d4f970541a75af417dadc969e6bb5f29415070e1078071472b5e043361e5747809bcb83af5cc5bb17b03ec564ed1349b563563233760c4553b0ce46a6adde8b4f1cbcf0cc33ccf6d8ec8551144992a0f530b012ec11e28de9a3564096637e590d549b8264c3aa1284270a9310496fea8d53024853bf30801c657fc2439f0446b3de62e556754805a5618eb99e3ff6acc52c898900a565139dc593c4b2a37fa9e212b646d9f4c7fbb204c2401ea0d838a806dc26c067a390f202bd3446cfda0a569c1cbd99be00c125ff13e330bf7b67f8e489c2191d73a74d3cdebf0bbc20ceb4c024bed7069d261cf7418fd07d305b03dec683dea3e3ad4f1ef8df8073f720be0761ba4c6473ae3e8344f76e7e7530258aae63b0b183b0d364ff7b53d35bb0182f8cb56bd550a5148737a1e7520cdfa5b11f0caa70390ad04d0e98664d47af518d6972fd4f803e5b395a68a3e08df1ae70e0aec356075f616c8a60502d45fdd6444ac5ed5d37d2f6083caf91fc5d9851e636ceb095169d44bb865387a60ff46a277ab2f9f6d8160f09d051bb581c3daafd79cc8d2d307335a7505573d2ef74d0f66ab4a432488c215b6b72faa1b672c5805f0e3265583947fea3f20e6b1f10b4dd717c0ce3088fafebc16d48ad74ee4cf5e059164700d3f50df68f2fb8d8b932918ec820c0de00eda4caf332a1139924cb9549c265339495fa248164c422fd6a31337a78320c8c31193101a9ef7202fe0ce9d30521ac08f0f71b3fe100625ff22cf651ee9494101ffa3b4e8c8c360bf03ce35a6c00e3a0a7f024f9757b4914cead8b17a52669fc31bb92efae1513aaa3c109916ea7c025298036cbc91c69b7a53d5774c1c28c9356e33caf4a5d6e9809bc11de2b3bb3f0d2573f8c28c8320b8a397ee9e384dbcad1d8a99d70cadc1c337d6c9c2207fed9f62963c46c866c79fdd4abaee40b62ab54b942dc2da4cd87dc404b742eaec64ccd087d2b60e06b1396765390f6f8c254bba3b0d5bc015100a67319fd198fb2850586b63d2d2b728d47aef097893178195064925954678bf2d7e5e31bc10ab8a315a0289c8152e7ce3051df782d81b7c49e4f171f1de5255b87d4801b0842318f60dda27545eb0c8797f77eec5a064d166da02f04faf7d809219fdb082abb41e0a59eb0c8eb4e7f2a260aebe453c59fb18794fe1bf21eb9eb330740081873e0d674f026d261f82b8262c2979a6c8b17a7cedc89a737f7a5a43e68f513a9c0cb084fb4723d230864186c8e465db6eff89efabc81c7b511453503847d69efcd625afee62118c8172fac335c0218adaa22e0b6b7a205e1cb0ec4dd27c769fd626eda9952cc2887c3e4e7c2586977e7145bd175ca45ad507a6ddfeffda0555ebe142cffc93ff70623f8fde34f24c6f9d654671bd784bb31fd0dc11da9bfe4577408527ec385d71ea1d3b739101083594e4e63f4156eb6c37541555344073f25e39cdc7a39c5a659f560c9ceab686cfea58fb62a1fa4c7aa3a35d91d4ff284706054615d0782bbb6dfb3b07a5fc80df69f1292556f2ff044d1728be0a4604118386c199a19d467bcf118b5b07b4a52181c73d6bda19f8952683c56b61fcf096067f00e47cd106626aa6e3806a80ceeb33acdd8ae7390252c815629473d79abfa9368e0c6c546624a60b011715b87fb8d5cc9a1f028f1079ade65b35291bb0b1fa5f02b6072a40a78275e2ec4784e41d16fd83357ab084935f6d7896788ce7cba108896c0e865b303fed152a8ec3c664f4b135739a671d3a8335b1960a1727d451c85f0e5562fa021088eb45a7f694371d16c21f7b136b9642e817cad5135901de9122756bb776eac02b894d04e198ae881e0af62b79dab09db20311c83e69852ee7b5c13a546714dbceb221b0440af333c3c4344f4fc324c301a60d1f183e7330f110ed3596e253fa8c693063f5f9599faa778b1afbe68eb2f832af2a6acb250d7236e956d0fd56eded2ee11caa420a2687fdf82a74785366aa22e916d75ad1597ea3d2f9a0c5b6d07a4d557a931022bbdd36b4bbc75e97c3fda081facc8cc0782f902771166d34c8ea91147d1c7b7ec857881fdd5425581f1d027ffd2108ee15a9b81196b29059a5791850f6f330b47bc5c7180db701fa81da7030cfda8e60f12a69172bac1651b7392a0927b93b28b42b5d2e9d590e736bfad55993d97cb1b79a1f519591e2c528bfbd0e5504189719b9cf4f7b0d155734cd43800daf07357d653f73370a02618bae488201846aacb31565b5b23e7aa818e70b5ece5dfe1cbeb945e449f3d425065925505e62a8bd5ea20f21667ba834d8cc52026857cf176677a658c7db9e27b0e0e0c479031960b9b3f6d06026e2d87c60c7135bfd63b9dcb2c00e46e5f042393ba7ff958ee8fa72c2c9e9594bb2fa9162c38688dd77c3ff7695303ce3fc79953453e2e2c7fe02628e53c52036297c0c2ac5f4630919bd359bb69225eca419c6a6c89c071d6716c6ec0093fc65712c2e7dd0be6ef7c7417aaecc60f83088b64bc0f247d038e921cf6fd1e47a59da17d62ed646fcc502aceed35870eebcf10881cf0ff712c302bb4e7eeca684b49fc90de7e12bd211ce2e0421d698c59ac3984d71d9b02164fe9cbe95966c4da5f8c4800fdccb6bc09e4056af229619ab9ab723ef6592c6bbf83fcc20dabf9f49511c4311a1a97cacfc030604334583e6f5ab08654ab43d9392722f40a41dfbd6035a5edc25fbe72ec02ac6775795a1fefa99c18948f548be1a636ebd24b697b0a59c00071b73a90511911d27c0b00926a79902d859a40d7f0a77488dcf5af259e818d05d186b0474a4425ec3abeadbe310922acf1ec22a615874764511bf80d16bbedfcf837323283c84971f9bcdcac612942fd12dbd1beb8f6b658da42f50863366552738016491073e24ec7ed6f429706ae4b90816471af4031be4e492c8c2a08ff1680e3d3d934f2e0a3e42cdf7214e3ef59af7b39842988a1f4cad45ad0ad419d0382f766560b861959132e76806ed08d5322da000d39845feaf455bc306af95a7684eea71b4ac31a972220ea22f029977030314b9a4b21f8c402b0bf2f41da5bd721179d7672ae77f48f9f682ffdf5bab3588cf8a49d31c002b7adb4434cfc5a05488ef8f26ac80dc153fabd6cebe61a04c2428aa04e037c977441b1bb93ed431c914ade76b0c08cc887e3d590f1e2a50308fa3c54b22d92f9b8ac39d485cb84eb6ffa0a51718693f58aad932695e169b7e41a4f4ce021362241472d13e2ef0c569110fa5f0d05f244e3e6f9b8a706817fa592b2f9117e8c2defa18ebfd1563cbe348c4f8de0a16e7acd71735a657f75ff196605d4ea3fbb120e954701c8c59e0bfeeee38f7312307ebcee061b4226d3eda9aad6eb31d460a0d3552e156f3e86489dff4a03791be54a6925ee5b07d0545896106bc847bdd561146ef646aa91b879f0de706c740bfdb5d1c3a732b640731436a62c431187e775b4880a0b2275a312a894779212407be25031e403d9f36cbfe07418dff4dd9fa6379d110416697ee0c114d113c6f99e04cc37286c3d6851c5ccf781250e5d3049d93d1917723751d8672639f0bb854f87564af445ac5cb47a1fd35864b6ae446eb1e4806a6f3bc9e4ca4bd191cf9d4b56530735b16254b920afa2415329f673bf921e849f0aa7b8c51f0e5b40756d04c19a1eff8b622965ecacf183bb07b2b4572630f97f6eadda879bc0fffbbc4bff7ed1e5aca9a847de2129a3c935c278af6c29eebcf58a1e6cf093aa44aca35c1bafa6e2a361218b000ff4a2a49c65e64c12344d94c5040d1e737f8bd78bf015ecbfea6ce19574837c5471dd660e673dbd703eae068521ac27f570786a952e37d4ef425607ad60fe45b09a228f18ee664d04652ee2cbb488d42a0c9faaf50f867afa41f1b68aa9d7967f15adda81deb18c00f29ea8a5e0775381cf931f58caacb54a7ac41db043747a218927fbebff95aa1520e136f366088a0c006a2fe6b61070626e0c083ede8c423acfdd70d0de04927a5d2f481d4cbd2485c5bc7aa22f6fe226be46be4a9dfa6d10253675bf0760f3131a11e169dcc62f4338fdc35ce0280f23483c2ccd2ed854b3666f6e8c02ca15be940edcb11e996a84a61db5b0f68fc6703a0aed9866396e26895aae65bde6d50f573ba0a6e45a6671bea93700223b866360ec5baeef69294666acacd89acf029fd7e66b37d0d1fdd9aa0a69a827c6506edd8e48a771cbd698b868de3d4d4440348f97a0ab76709d57139a1da8f1b9543252bb8778eb2f5be0ed17756e4ae806e341741dc992dd2f06608eadeb4cd819ac791f0d30901e622bafee36b5409c091193e4c0f5a5db5c516cfd9e40496cf91773e6d87817f639f8d47385df3a43a2bef3705c25f636414f9c2887a782bd786b7b1cde6793907b15eed4e9486c991f21e3a02f7d48dd9366ff8760d95a46751cf1d32c2e72515f36e0d98ad9a5f81a70c06d5c4560868c6d1990def3b94475b76664381f722fdabe739066c58370aa03a28aa5bd00432177b74d70f4cb53ab7f3a5459e99e1b430d1dd547c273214dbed7c3cdc673a0f5b924a860cce78aa1e8cca714b5f28471368e2fb5f41d2e72e6967e20adbcd5006dd31f644b4439ecfd62541f69d5c9810ca00df676a284d4646923f76dd4846d7f289d29cf3dd9770cc4fc2a2fda158264538584aabd66d28f71018252892b545992ddcdf4a40fa2f3a909abfe0da2e722178d70e83ccd21477581af360c93d33531b095951804c15f2dbb80d48a9db7ea9900edef9651f758c97683eaee8e61c0c88d30c4969920aa732c57f8c5a1aa2834b9f9c3285267dc4e56a381633d466a64b2085abfa052b13d812a6873efe6f2544650186fea789d6924599bc06046f151931d7b6b614b836a1246b8ae7ce4614563ecb68cf9a57cd3731f89e1a73951a2ace26289a366529a987592d18d4d326fd0a9f289a6a9517d4e33de1736ea2f9c5e2c52493378bfd5b4fb643eb17fa154728e29ddc1b2d6fea380205692aac60d3916ec163777a6fbf2fb8cdf840e09f910e29c85727812a62dc3a3a39afdc2ea167a5449e12c2ce1371a32d57ce5802cda1f28254f0d9c544080622df00e2c094011ea97e34edd702de6a84c1b156da47667699b63ada7d58c202fbc2f540c8d4fbf8cdc95f9b102257fac1f2f8ce5bfd2f50e99f7282d2463208c08b106782a1ebd4a135ae1afcb54319972689303d6a524307e29114a50cdb2f8c94fb0f204f637a16fea8261ae51ac33b3b1ab498213636b9c7f855b9a46308ffa1f8b6c8b25a2b6065920f9a20833f9c097b8f48dae00ff898d7d462e55dab5aa07f9d1396504b8e42eecec392fca1f64c30305e02602f5b454c4a562bb17aab60970d440d913b8db0aae3383e1f3f013d7019e3e9d69147810546b1dc6fd68c9f47ac3c4a67972b854055f4706ae4861e584aa855d42e4b5dfd61fd9d6673beb5801d2e31bd7dd78091d474d7ade651dbe5ea208360be3ef1aeebd9e38681768c0783193d1c4474f913a2b4c395ed725ba539a6d6a0ad31015248c84805bf0cd35449653e8801a6a397f228d385e8cc8da401fbc8c111de9dde1257c0cae82220202870abc1a1112b807287b06d08f9d33ff02e81a19fd66f02ce48b71524b5a5177f80b3674105d56234bf717bf682f63943f9a6464638053561b78db54aeb6525035b39a01e610249af2c0b5f2b3b799f14f8c0ee76b66f09ac685ed9ba4678268441d14a22a4a65fd3d7d72816af4d842bdcef9bd20ecbbb42c6b6fd6668bcb0cc8c99fe5a30ae7ee5c850bec2d6296f91c2c1976fa55a4c9cbdaaebdc8f718475951affbe88c3af773953001c08ae069e1cf40bb9799f569954b33c3f4330c74652f088ab669c8b7cd93c5557be761764be9e85b0f07439d28b8e9977586922dfe4c287bdc4122fbe6378923c86bc586fb547b1012f92b2a75047f7a48f88e1730408bf53a6b6ea2c905d1807916be1e0288294cc466ee73f909ead23f31ef36b61e5df581f382c81aabc761f45547288621d16ba21e52c14b92c93e276c22f2b4ce5106928cdd0cdeb67dcdf8ef98db1a701e9f196a2cf3353a27bdcfd5ea32f8cb53795c40beaec2e33bb3ceeb980688709a6f875a2ea891367aa7b1d5b5de2f90d717d2efea3a3ab71777d1f4c7d758487f2114f5ad4062b31b08fefd3edda89982138e4185ed9f4cdd122761389e06bd4eabf217d4197b3fa1a0691a96f7b1ea33624e528132c104b25f0440236ee38df45c1581a68d1fb44e1bf29c3a191cc95ecc2fe09c38c78bba281cf51d51f06a22ea1cd6476b077c6deca2c278606fe8d6efd65dcf9fcbb7e984d75e69ee6e1989427c510034fd4501f75ffbaaf813bbbeb148dd1019d45e2e6ad33a22304f9cbcc54b78c8c3ce958f8a75a2a777f092dbe3b88344f84d93dc9bbec0aa9287a9859c740dd4dd7bf28e5222cabd4a525260a94996ab21d70c4c82ae42d7c802dc9e7377be23b15e5c13872b0a49ce3894c60bd1aa235fcff8d4af6fb85656376a5fd0409fc4b33419f9a4f70462baa3534bb8ed68b8ca471adf0e11d5ba51d4b614b678231e3036fbd5c632d956298ea9fe845727486896056d0c03ccdd1c9e8a9a60473db4e6face0c4edd3d0353fc588e24e6b428050f18974d8c85c7cbe95dab305b6720dc14c21b1550743e335263c756399ff8091f48da7cdfd9e1fe4790cb337e8db7640f2916fb910bce94e76c9dba93ce0c72c297c340c76da7895a75729b2e103646d91170978de2abb1544927d473113947c2fc1e048cc08bde0fe3e5e0afb144fde4fb7328545b05b100e432ed26d16e435fe4d6c0a4413a8041614569ccaf741e8d3e4eac01490c890fa924792a080750f582a538afcb5851be494f8bfb0649287fd01b5fe10f7402ec63899c67ba5c2d377683425d4b079b62e13e6debe7d6cfaf1f7e8f6def16902a725e89840eeef41fb54d74e97777a31e5275cbe2c6b49428cc11c34a334f967c3be7c8228b77029e494a7f30f0f774f9d7b3ac9cbb0792e5af1b1cc7bf8250b879a558fe1dcf0e47f9eed867580bed13bf0880693a1eac8eefa43ad554f64f8c07aebb280f71112a168c320b4a2cb757c2f0aba3f7168c4dc1ad9a95a959ebee8c4057eb6a67df2d80a815291ab340fe4e1c7edc4ea32ef97eddc3a1806d4da1edc07ab7362a215be04c47d9d204f644ac4463a9aca3b6620cae9842a2c4140c724fd7f73ea8a7adb19143907af6e3850a5851334062cace2722124fa72935979ddda0aaf71b3d0cb11b3ef12e955e87ce03bef2f686354b8023b45933787146beb2844f6bbb3e4e6278270b700e73b3b2c4513a9e8de1fbc15ca0f7b76f5386acddeb400452b6fe7e60d109ddf62a3404b1b3738de303d0e824796e1737c35e1077af37d5f8d915c8ab71a16635c60e18d76b3c9280d876a34fb0973b87ffc3d4761075e1f30a2be34621baf1c73cdffc7f965e590a63ad34897c27047df2140c976b62c7cc9f02fcefd07d9c0ce7ddeee9cc6dd7b20245a7a08268e2246044e84474969e1eb63930f495750917bc0975a0c65feb4d5a1d87a2ea7e1508cb2436f319adccc4618bf5bc1885d0e1fd3f254d5779037ecca9649879f1236cfd843bc832c2a7c2d79e6775fffa67da8bb582e400b36a5b95a7efd3bc6d33dacc0e2588c713fdb46c87095b629294efa9f197784766cbc697b84c874ff109705f2c0b6c2570b3d90f5b85d84a5e1ab2a037136d187e37a7cb33b406b3011fa3897e649ee63ab76022db7dd2d0eb1b7ae97088b19634ff9970bc1cedd6d20f5c67772e8096c634a7dade70f5f92710e41ee9d8dc3515d7d1d73a8a6190e1db33e2066bd26a9e828a1b8f90f7ff12a2f23627f75fea4164c19ec1ac04b942e6f2013bfe2c2e43c2b57f3b21024429b468c6d1a1dff7540614abd4bc82d5d9b059bde8b1031f96cda606fe9e94136b4290bd046c5e2818ecda86bb7e1fef74caebae4d090b6a58e12edfe52362a681dc64e378ab008550c883fa84b062b778fe2db472f32ca3fb2f74df7be06ef0a85f2fa019260c5cc1e66d7fe6d6962bf8762e9149a689749f3b871e88e5a8d4a61490dc8c701dc8ca3e920067613e907f5c736d68c792672895b47e9e797d0253bec32b9d5a79e0a433e1601d5e5072b7660b5ebed7e67bc95a6223176625290382192efaff0436ff1c704e9f76e1c64d83fed9472197a6bc000bcc24d02e5400efee09bc5881aee9bc801826cde13fc6d22a0a9dbfe4cb171c9528a0240b8ded6f922c77de1360939fa0bbe4fb82c3105f22c90040958b1cfad71423aa7fc3624e0d22a4e9da57e3dc09950a599266fa71c0841f80764e96a096e1ce4ad161c0cb5348bb5248513b4740748d10b423b9cbc95cbe6ae43040a5eed2ae2cfc7eb34081595ab6b2dd1fd7480089ee2e8fbcd06c6dc43a3243c9c4450f05c28559df8c0fc41cadb644854825662d1475c00dcec00818b746a286dc12acc5175a04d0ab685b48c76b40bd0790afa606be65e6c7df5e027f8bbd6979f00a08cb985b68a64f1604e6386715a4aa242d8176e43f6d8147dd64377a4f44d24fa3ed06323746207d95bf6323b61b42f4903d32f6235a77f98c25ce6ebe8d5f8b76d689267ecffe9c32b7dde34c7f43da41ce215456f1423572b78b116af081226c54eb0fcd8272890ea4ff1ccf91614c309cace805da498eb7b538f2f5e08d99f46d1f57981c5d8488301fd00d11f484e13c00bab448bdace012d2951db621aea02e2a1efd5638931f55faaa0c62e9a3d25ee26ef6a57ff22836b331e9d4d9179d5297972891bcdfeb695e9d296e61798456f9c7ace85c8e767211c5b586eaa114c74dcbcaaf8acc932707f42c775032e1f771428bb60c6fbca0e34e17a20ff52f4616516c60ff59a0b81f9908faae30985bb3126f98fd57aefe7e5b62098f47f35be80891ce4f9c4c6991b817128e3917b91d6fddb764b19e9e705c9fc3b45d1bb4fd4e0e06aabb40ca9f276f618e98856fa6eefb1646070e7504247df6dace32b472aa7dc41e633f086ab7d4ff34874c544d07d5679e7a8ac5f36672cf59ccadcf0c002e9f9322ca34a1691690a06b2f6dc2dd5d1b705490c8bd3acadea5d4e7dde44bfde584a62bfc85ad067be0e3a733e27ce017cac0230bfa5c53bf423dbd2f02ef0b95678a215afdd0480d0f1d7a1c709398e3448eb7b7c77c33570dfe545a81c6984c1bf19584953641daa62be86c17ae3b0c39daa12e0ddc5c40998f64abea505af6ac562d79d5f33cc19954348b0ed03028e71f6ee00962b0a3cbfc3ed78e92b58da538e8d4f65699a96bc41987f1b13aeaeb6fabab6b9bc9bb9e30ebb96a7a5817b73061d368a356f3d332e77da5e0f16d5f4fd981c132ca92cf6f6ad0f6ddbbb8f20912c4cb8a806e3386f39b7c5f668763366d01a4d69b5b0516b1b8b0930e7211cc060ef0d0de91e49656ffa28cb3ba42f4c2a31892eb91effff5f607b3bbcbc61733e8eff2680547ba75f37d4a7a6fd49019dabd5844aa2077dc5783919beb2c0a1f2601eaacc0ef67d61a70a8c9c248de2af03294e86f555ec59ac8c86d78a35c450ee80d7bab2b72761412cb54250b27aa3dd40b23532ecb3a14fd7fb6d0ab584a3677f6b1a373a1400100439edb5e011c9595daaa69fbccbdd1621f8ea08f21d4ba9dec01f2b75b6579f5010bf6538de8240a266eefd7e2fc9f2096c23465b5d545627737f162f8c5691c0eb07fe59879d55fad9174ada4043b9ccca80e2c9919d005e339f71802c6e64107e5d939921989642da4e3a24ee3d58ef82e99a54a4d4b2c732d114a823d6edafede047b8877713abd0a37da3086c64abd0cfbb2914d41fbcb6c33daf9405e371dca44f9b085bd7ce80ce5dc10847111cb72a6fa0ddc4d4f5fa7284c4becc389936cddbd759338701adaddcdc68be01cff14f472d30aea3189ae4dce09afbdc6d41405e16dce2f667bfba5600d7cbdec3d4d30041544dd461fa876c085c15de206ea8a00b90f89b5b010622d246b63a11dd57780c09e6e66288141e5191c9aa4d3887989cf2960b5f7d7d0a00b4fafe80691e335e8836cafefb784c05c4c13542d47123df54b71503998f750520e6226690a6d0e933adad8555f519c8e08d4835ff8826d9e975ced67b2084b5f20c5e2e2de0f32bd0cb3bc760174c9e3d383a4d45af9505d2c1cd4ea892cb0190d0ec47f1269623937425aa3725366ac712f7e30358de56b757912fbab0e73dd0d5672f0e23ae501930c7cd82b10dcd41815ce7135b8013e8a5ef854dca11b7c984d9da15547820604df6d0e30b896da0ab8329306220a4d095c610566196961f840733f872dec575ae58c11cf507248d3a5a017bef3c939bd05b789a41fa6d0ee0e41b72e62aedefd033cceae2e13404eaf2f3ba109c6cdb10cfa8b4e6a78ac3ee7978a273c999bca8a58930f4914044ba6605638ef5dff33b6b4b1fc7cd76ce502060affcb5232760f8aecf01825c14e3d1c0332b98a01747965b8e62c1cba3a865754aeeffc1a3fe38683a0ae89f7320b1ba314f1bc5dc2b47b094ba9242e7473245e6feb8e5fa63699f320c755e4b81f8fdc22d277d62d50bf1ac0a33047b7ef43c9eaad8376e3049b7a772cd5a21fa3a1358efa46857699cdf4e26ca3541f8a508b9f4baead07e9b8522081461f3a965547dbb7a43cd53f804419bb9ecccd7e0be09f69b07d320d52db53be1be2f6b4dc4ff8b7665681e9ba4cc8b6ac989bac9002a15913d0600e7100cd086494fb0d44da52a13627adb6089d8634288b08e9843ce090e79c37a286d9facda1126adc9bcac24faf62650f793407c36bb71a4e26526c7c84521aef3a7c702773ec2e4d9648a2269d86002a11325dd8eebabd321a4f6478cb670b8fc5b1ec5346b58e57915a776dd1830854a81f2716b089a336d3c4c9bde6337c9ebb94f269d9990028c04fb12ca59c2eb490470e33534d8efb250b518d7e2b23d515a716905e8e5200343adb21ee504195f282c913534a76452a49c76b8f5c33a8a174f5052dc3db943565e6fccbc36e7951a1063c8410a454b7fad8e54a021340062d2fdf94981dd6d88995014a11a7dbe244b401ff88d6f780ae1c0945d4fd88c2c3426296bc2c80");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSphincsRandomSigHaraka()
        throws Exception
    {
        SecureRandom random = new FixedSecureRandom(Hex.decode("7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2DB505D7CFAD1B497499323C8686325E4711E95F8A383854BA16A5DD3E25FF71D3"
            + "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1"));
        byte[] msg = Hex.decode("D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8");

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.haraka_128f, random);

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initSign(kp.getPrivate(), new FixedSecureRandom(Hex.decode("061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1")));

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        byte[] expected = Hex.decode("ad45c2c172a875ff90f5b600214b341c22434845b18cb77fe977678c3830e2d6d387ed574fdffea06a0b7972aad4e3b72ba005274291f10abceb863ed15a5455a215a1b55b9c14eecfd716ecb5d33942734765a6c3a2dfeed163ec21d2acaf1110096fc4e1825d19f5313a4656eefab6b62a8d590a44931b184cdbf838bee7e94524ad3aca2392c19fe4268665c7f75bcf45de743bf7aea486ac9d416fb9b8027a87f69a9ffa02ea6d56595086fc01f1120ef4bdf56f72d5ea7e9d4c53f45bfbe863bd38dd9ef91b4f66818d2d442ea1dd244c85579c594b0d6b22d376e67a654152de8f4b6a80c703f72b4ef1adfe8f025e4ee56d0cfa0734566f38d3e0234f4be9db63f564fe4476966c6ba7833f5f3eeaf3a4635f161b19be4b0eb75de38750bd777d21cdbc08cf2d2804cbd34d7e8b082de5cf58ae54bd69899bd18094f07d721e8f0aee801a53ea72bc067aa650b3911fe55d840337a987708406a310293aaebe2929e677ca267eb675433b51b156de6bcbe358ec54a1dcd79eed47556194b364cdce6fc25094dcf7f44f108bfa13af2420ad6e0ed8346675c902496d33a120aa94d50e839f5f09b5abb5fb5e18764ec2a3f4c3c718160bab600c8f1d61df888f7772326d95f808f29d8791f0b37ee8806d279c9c3bd56172119d24e0bd024e9d7494279c8429dd5adf7a014747834b56a67e40f7afce11d9e5203f32529f552fce849878d11efafc472fb1384ae36d965d6ac37033ed93e607a85a32511691024a0a20347c388f599f72053a1a8b87da1a73d792c50a6bb157485f621e97810fd3e664d9e50862db23ec16b20035542c093c7517853da81697d3c899f3bc447aa2f5fe5467d6e2377ad3498b7db3076bde0a342603f8285e53a356ae981e0dd5e5b80860546cfdea9d6446dc41174b1f30237b002901436062607240f86c4c7963f5670477fc22520fda1b9d68d7be89687908dd2005f145434ec1d87eb9809d52ac8c38e414a5fcc6cf5a0a2d63d9438da9755a179bd304dfaf1b5ec719a02bec558751a21613119db998a313410054f7567655d286a63b351803f958380729c33a9a211c3ad2a510faccc3dfab59bc18129a47bb00684ff4855a915a1df3c75872bc7c0ccec9fa0e406a7a79984a7e93b7f712456801c241535a35c14b110189b6538329ee9aa9bfc6c7467c3bae0839ebad7f9ff9bfcabe25895135fb6dbafeaf13ceef0df69118a3814b3956a7dd028f493bb6fadda1878604e2c6c6b8cdf080c339600dd14280537eb43df30362d10b5bd74d4f4b0d8f8a40c5d240d287d6f472ed3ce6a0b705b1afca0e696473151bac7f0372f615615bf6a0d28c8f41d5d888fbf177ca9787fc8995e97bc3cdb5ef289403116fc04be9cf4929a0c2cae4bbfefde3cd62ca29aa15af1a1ced9261900437eae9fbccfe4c96bb10dfeab69fdb192799f3f1e07f61a5e653be7bfdf1c5ed7ee369e26897cdf8db62e670246200630a34ccb022caa722e3f99d54557c3c8911f253a7f7b1585abeb5644cc687715b9382a0f992bcf8d4ab3a54e0ca7d82b9dac6eb042ae4a200fedb39144f5372d6ee526df20a37c6fd3e2926198acdf58da331c2e6d8a7bdc81203117d3b89ba12fdea5214a204c5bfb4d939c45080b6a993ba2833330252b6fb6e0185834d167279c06e437bd46df02adf6233509d0b26c7401fc1cc1a1dff20aa0aee944a3dce0bc2d3ca0eea72c975c7330c56a499fcf1e493cdd96ce4e4635aca183d9e85eb8109fcdbb891e1d8826178b6783e94e9b9f0aa79d1bd4f78054d8f685c751ee278b53fa408502f90649627d61a4393b59a1394479287542dfb7e0405171cd30a48f0f638afe629ede61fe02881abad0395ddaf068b22fdfefd4d9554c86062a53e27e0982a9ec8026f9ffbc6cd5dd9e9d6db27d4611ec6381e13c18881e4e98088e3bc5f5e8494fd271d5495a29baa3e936e02775567c44150b8c8b4dc2e81009759bec3669a052b51b12ca7780117e180a8245dccd523dd3c7af0174702f8dc3a3b7249d7ef5ec32a148aa2dab15b60b40e6b6316d425e30dcf326851d03ba0a1cb67558b6f6506e5f0ee41b696297840a76a9f7dd4a1cfc2d996d0994e6d563873b7332bda96ada2c7bcbe6ebd259653b294090abfaab520aadeccb33103938380d4fb620f80165ae340000f6a88dddd13b1f758e152ca0d80c6522aa5d9b59ec2b100918cd6a498b6559149ea135d1fddd426375a32571cddf9c72f4435c958b0c8146cf39464ff92e7dd3cbe45584108b9ae2793396282616837b273a06eba0dd3b0bb2d6c30fc17e14db1329091abc649ab9068e750e4860f615cf449f6e9cc0517fc0abf053ba4d972ed6e94cce8e31fdaa6661894fd0b2990f7c9209e64d1e7cbbeda2ca2c39800f094408bd87e90a17f9c3928f3a5fffd66d575e7b6311b6c21180b4a3461bf5d4d290bee1caaebc0566c5407d79093ff1d282838e71daa67aa27aa67f42de583b7b6b71caa76cef2e7f2457445368d1e07d52a83d1f327e93a2f030c190ff09ff563e4ce0da6a8beda2af819352ca819fc36cf459b6e7a7333d11e5498c342a6801a6100b585b9a8f8b9504c3e21a361d0ef40eee8ae447dcd8ec92a62399c92bf35d3844cbe60b2623cb7d0b010baac2055fecc519e1e089c3e4c82cf96aacce6e03ad8604ed7dff0a9d88e1002b59c3f157ca7649976b33a23412d7b97e7dce3867fc18f92ca7ad5f2a268703eade7b1eb36a558eb590dc3cf5003711d5c918ee52ba333a123dcf7c6f3dd19f8294908d975774b6bae4f2ab704d9fe4c6dc269fadda0f855810b31eace757f9b46c9abcaaba3cf405a9c674eaba287be9a7bdb4411bfa679ac66f68073cd0767e83a7940854b106e8d972045f4f82d13dfd94f69a0546c1a8b5d9be25bdfad266a56180474a8d385f1dca8c4e95e80f7f1147ebe432ade3a2df7404efd9cc6512c72b341b4db7471e3d9a170391ca68d6a57b3aac82d34f2a9ab2d0f073893d7aec303c3981504913707501f7a66aa36103218413f550714057ce3abd31edd1ed8b52f81bd2afca5a781271d1881444dce071aefcf1b915ec4661b05772a3a522740c2e353b0fc8ed6d59942ea340ad5fbd8554ee612235dfdc16cb37d5da873096d2b1bd8449d2d775d2d83dc15712d64dfd638043568b9e735a06485a19926db8869d32b0a2790611f994c085386bcfd02acd59b9a7c6381b209e3544ae1e8d2f43cf1b8877a7f853fac115dc22e24a8c1d01fe907f8e943fb6fc390e24bcc2bd076b3fad563ef70600e22a90d6c04b967054f8ed153403762234518c919fae91434c80cbbeb01ea6d84509e2c24d4ef2e948ed3dd6940fe5c1bb313e516bf145f0aba9e16c0b399a461bd76cd4231574239325a00d70741ce5d59b54331c6aef2e02655f6fe68bccf6b69a4979d4aeb1b61847f66259287b653e1a69d42f244d99822c32afd891bbe8253dc9bed6deb600a9f2db5fb4e803d4bd8c1f5c4073cf6e39bdc284b6dc8109991fe3b016057cff96175f0923d4d2f5078ec36ab4009776eb7c9d7bf8e819e049d5edc5864e9a1adc693d54120ab36cddef0beaf234b9690cd4fb11d6b8f83dc6c4edeaf8f7d17118b0290db8a301b8bb951fff6372268d37deb4b6546b40235d38768e6080cb6a7ea7e919501298904a15e0f55d7960a3d2fdfe7e9f806893ffed54669736b20d2a42d5bc3b0fc2955b885addb507eced11440c5e5d3b7cb06b7e8e22b8783d3be565d28d9c44c247d158e6e4277054d750525a5aae595eeb681428491abe5f051313738913f2eb9ecb2443478aff3708d5fd389efb930d0154778bf1f777bdf26f171522c0866c154122b239d14cd52b5c9dd1cf2fc16aae0ad48eb51737b49407e9866c8361c4274a697236cca05950e4211abad9ffa28fe1c71f9e9cc39877fee317433e2d5e460e98ce394eb4041f8976b4bcc20cd1b26191a29be5c13b5b5550119fe1366a505d1179083834e677f35ed977872dc423841588f714b2bb06316470c6d6ba846f3b7442000d51f24ef451da8772e1b1250542eea61283ea8ee564742e765a80dcc75554752b5de0b65f2257cdb52332a607b7f5c23c9fdf187fb1a5bddf0f3744f20f104db63e5b2955740e2d113464fc184a032374a0bcbb947252593195ca678487875bf8437d9959fd43fe609928eb8d0a0cdef59295849d13ba67c4ec22a244459ce01d1e836c2d54f975c6c5cc115eaaf2e8be089d7120c98574584c98a08c659c7e0d77a52eed8797bfcc7176d1dd33bcecade79fdba3dc6e9dd921f9bb7142a0c76d917f694d33a53db43b41ff149ea359d8735f4ed09e09b2f12003e5e081459f83a1953f01d39e25d8f8cbf60945228608559d3981db7edf41d71b05839cf67f47e159a4bd8a74822b1eeca60766290d0bcb852f8203bf6e1540ab359dc24a38eb0d6e078b14c195654d8136638ded8986b627945ae79c8a7a8ed9dc266e6a4ffc18ccbe5ed89a227dff0e16837b10035ce80a0179035a2d2cb6ece6e6de5a7ada875471f7c024da29a507cd6207fa01b4e6eca4063b4baecb91e82571171d9a48a68e1d418d010b447b4947d7326b1e0d42b29b09acbc9a5cafa3017b0edbce6c5c14ceac7584b602ef97526b4ad5879f8839b6ca6d8920e87f8c4069061e760f6a01259772876bea38cff55ea8d301d5697c918479acbf518a36cdc76462e4a0c654ba2794ee11a98a8014375cb756161e367f469eba8b1a633c0bdf57a2e5a83afa4525142e64612e6e675ab92217ca348263a9aad5b3245a9c4febf3150e2c93b642dd3b3cf9f548fc77330835013128d8c2568866b07aec7d4ee429edd0fb402080a90b3c46332a3e5ba46bba3beec199fd0bd6d59e7ecb69058e7d08f010054762c1423566a7b19e3a5c23d25f8bfd37aa782e6eadee8a33e91ed5702d0d8596f8dc2abcbe9c72f3e49f023d60c8da77ab56484cba7d94ada9448ebaeccc7e6c49ee5faeac7728d27e32df8b5fe9b0349bbf97c84178aaac0a620c7348ce4b8de9a11bba85ee647d56d938aea848e85fb875c791bc0de89e846afe2cb90b73c04922db7e74c5d0518cf21cb82431fef8f140a23053ce8250d55e9438f8400e8ec0a8592970d2cf22fde9771f145b720ac8a9b0458ded304df7cf7bda9fb6ed899238bbaca78aad28679878e5c7e73d1ca4190266f89c40a2a6eb71f5074c1c966c765aea085c781cbd464e50db6306a2d240c7ee4d2115df4e8fbaed0a0383c872cf9d3f1904e923ce75437b6c9035f3ebb8fa33f2a1d6898bd23baa53f33e492eec49f5f64ae6be4146d5ab4e6a9896e8102ffb570188421016595b8cf9302b064ece95bba9fc7a27d47c8c4d12ad47f5a450e242717993c91cf9a18a3510869aa919826672ff233c1a2be1eee71cb984329cffe06d9e714c66113111907d1a50c2bbaa56f73abef84114c158e05f2754f2b897da3479faebeb29d2f58a03564f61422bcb4980919da27a656aa421ad0ddcfab11d20d3cc740f132c14a143e123d5ffefff39e49bb03757cf4cfb59f524b3b8ae3cb4be47a8b2fc3573c480c793857719a25fb9c3527391201bd387a0e8be6bdaace3601f19b997a0fce427f1b07b3f67ef4b1b02f837438db49aa6b8d5ec06ede5d015b03a9dc53d987ee30a14de58979a998a6a491c0771b09a9af2f7c09e4db2f826f207fe5eaad238bb07176727231c4276154906251bdda7034995c2e6bf806c36fd8266b2c659c96d450d4e06c344f8876cdcf16a3eda0d2bece72fabb98619a953c2af627635e884dd65e82e52379c1b8d6069b1ba8fdbe737cccc7c50a9964699250f2a68610285dcd5731cdc10700e2d08eb8df501360d2b9ddf8e5ac315172ca3bba80bc8883bd726dd95460ba56f65a55a854b01256e6b72e08936a65010fb5961e0f0c2f39aa0eaf256e205b7b7a9ce891336588fe0cae724223b07104f0dc0f12b64cd1679d39e820ea239728a0b4c9f507b27fff3e112105872a03e353d7350f507789520b7c6a15b14c9c11f15b2f822ca231ff3cacc82ae6655d302ae8f937eecefca008ba7b25cf24776688125e6f4bde3a6b440bbc4d2228024e14a6301a87a96390936464a5e093f965ecb7e5a62d74c3b89e3a82a771160e6ca1529379261a9b4248a5318c35a139c1cc648d5b0b5ac53cd88ec3ea66b30f4b7cf30f340fcb3204ab8bfb9903ce255af649e65df30192db71144323128e7f162a51cf97f758c00c287d23ec4244d1353b18106f1990545455d75969b8126d41622ffc3210f41826a5f59975ee602e7dc2d95e3b5dc44502cd7b7638cefb83e2fe4e66a8ca297ce008639d8d20171e57ae6742ad3142b6c126d2e5066e80c45617cca8cdddce8514314048a64d469469abca77e7d93334861067e10fb6326337c0d7147424d9242daebd667ae9a0be82f76347e43eeaaabf7b996ea1cb11cfb03981a310bc414edf0d8ff23351c62d64234b765c33192f1248fbf1914a09ea219ed344da3ae70506b33ddda772b94716da4a5ff1d9da7c2993982fd8080d8450255b484c7e59a9f7048f8558cb5208b758ac48a8612c8f0062c344ecef0ecd2188e1ea62c8bf50d6752bcb7d85078b2d843d6b8c3339a5b47134b2b95398608f3d1edbc76a248fca3bdd4fe88d3e3887c8e029c509ca78470c452c20f3f737a5c378d6b0719f876a0be6c83fa88370c6cb70ea37112aacb65a458266e4ad9514b8ce878818d2fba4b7c099251d82485d6aaff2051ee1a4d163ea02d925ba9fcd8f99bc653f17d3c9cac02164b383faa82cfb2507f70762aaf89cedcd77f01687f6aadd521f8ae01fb19e23910662e12ed62e0a17cf9d7136b0d222e301a138f8a4ec9b09ec76841c0c092c7e8139fdd429b3377c7651a524b11ed52281e4d1dcd3fc8ee267d353fb330a1f20974a676319e561aa70483931121482079a1b4ef520de42dfe4ba73b2af36747c9593ae7c5ad4bca6435d08e48e899862b419454482930332b4a151189f7ce9c034bcd6c0553a820a3076aa46454b3120c1e33d256fa24449914fa17a125a611e268a4600a4b5ac01f236c8faaafe4e6495a09781367baf51744651732b1fc2e8486e00301f92fbd94cfff0d1f315e7252fa482e9159f4b6f1b921ff194ed732e6e058982e77f78d735c7f76dc9b616183e2b67e99d1fbcd25d6f702b733eb719bf9d9f68215a621700d5a3526f803cd41faa2d3f120cd89084f46fa5386e2c8a8da23df8ee96f90af578479c2d6eedfc886cd14ee3be389d723aee5bb06f88388914922f9fb384fce291c1a1eecec80aa1bd58fc7557652a00ec144daac630352a13b6d880f219255e3a03b9d830ae36dad917ead26c1f36f2b40373de7e0072f6eed9fb736df60b10f7ab667b937b393fa15880f7c98d131f2bd9ac16019f607e3ef6e70c7f8246369c3df5c544062eafcad8e3a473511413e87b1ea2be031dfac70b2b7cd718fa293da95e5feeec0e2f128331dd27de8dc3f8c63f9bb25468bb8cff011068fbf1fa6a0d325b88edd38675d5163e0784830d13e379aa83e1649e863a6b313fdbf521e1803f0d40492185cb2ba4d763f43c0b5f0395fe0c321e4c58024a83c5d0e01c214ec4f7914add908de5f4964acbd3d583a2f1263f90cde8186f7b759172ea641564247238a3781738b60769d91ce675f5ca420c0f31d9db1d8f60173b3ee857d151b1b6546d4596bfca66e8ccb9476537c4104e7d693feed23dad66ae9dba95c2dff2a49e664c3b66a2063e3db6fbf1c510d36c8375f1f9e51d97e838158076b5b61600a10074d382259474a657312811b5cd7344525f4a345dc26288ac15e9d536705f70ca20a5623e44780098a49569a73b0726dd16bb1db9f67b3dc42f5712612e69475bbfb3600403b9d949e1c5f244cd836a0bdb8e93b0ffa4b50a57adb82e0a069948c3c77b8bae2aa7109812f665e911809446209bc7244bbeb35eec94e3dc17d29dad4b6a59c21bda799cd87fd0f88eb3c73da5e221926bc7b4c68485ea1c538af934b8e538b1e328cebebc64c191f05219c0f4ab06752cbf4feecc0861f6b2cd70be2976d309153f29e5efb15327facafa7fde3e1ec0e9c04269d4e40551539ba59382492dad8b72de4f7ac95f97a14ff75b259801e7382a7d7b7a35af95a2485876b7f83ee0923d123b6e4a6e0326eb7ad5f6724a80189982d6a44e87465f22e3f5af6f5e1a446c75563f970724f63819618f1a35f9d24099c1b5a5c2764e6ecdd7cd4caa2104e40f8ececd93503d66dbd0647bc3aa865aefb1d53f4396eeb04f0f5ee9ec9c87720ebd8c7b373b7aadd4d356356ba85feeb7a8d251c6ee37741fe3aca1f1052daa5aa90298168720fe282e5c79a0739b41411a324aefc7a492007ea43c543ccde8703f389830eab418c7c700bcb6c0634b24265e0c92b396f801c35539d49d9d48bacccc0c6b2058d9c0a1e91560d9430e738634d2b1d86d3bdb0b5f10190e742048d52f4c174946a336e982212b2f66eceb53be39df60a6a22b02d3c543c4ed2cf2b192f04a7af27995a5cee18162737e63c6b02e02fb0fd8dbc086a2a109667eed37c6febb089a4b73126e3e97be5ff29d29945b5884df9e2e41f4772d0ca72b34b340bd5d8d9de45f3cefe0addddc141708f1e47db2ce31902bdc73497efb98eb5a1ea3d0d98dc66498f813f68fd17850422f6af23e9370ccfafee1ea33a8dee37258bf75b407b4d072e332e0e545910871bcd8de57deaf58526040b406de2ac966565f049d13fac67357071adc79249ec25a0bffce306b919521108ecb4db79f748888920f64b79a7930e4066c19850df6f99d59a26b023b9e6245dbc0f57c997f545e1acfa8501f2b7d27389b4ab4eeb981155d83cd4eb2450e80019e5901c2e7cc64d391780ce865584179d048d4c9699db794cb4f5098baaeb32b4ea5f22d2a355bcd5e28fb6fa1a860f34df1939fcf022d2710688c7c3390f8288158c169f90ad305b1ea5b1ee3e9025b6ed7a82e175f139a47e18b6eda87d742dad7205423925d7739b99b09d9d1f4d0bf17e3ffb3cfd632b0ce4b5a533fee89d7885cd9a1f667144a0df55127167fcfc003bf26174110f5789b8b68de465f38048e0cc57b64ded2fb81910e8ade92df01d5ad42a179d7cec5abda545c4476b9291d594839fec3eec3a61cf3e36219dd71d99934751f9f4ee3aa7cef1a7f6c8832f867f86f60f5ae07c780edd1780a2569bc7fcd3402c6cd83ac8ad35ba30abe7ab8e348d95654c995f55161f88db39cf084be619a3fb0cd4df72afcac9e73d811cd9d3f682ad4df5a1c5505c9940fe66f39d700276473e8891feffce9429a3e40e591ddb4e017a4b702db99fd6aab83a5a931dde545b22407decd307a616bd8c0cf50d6eb13139a0a0944245f929b75c5a854d288ff5f5e6703c4103ae5f4112bcea0f9a17705b73e3153129a047300e12937439020310dcad9bebb8d8a427cd60b58959075e2077bf638e385b401b37218a8aa7a9a4ba65394987f844b32b18a52e74280c39360133c91b22aa9dadf83abb4fc6b75c5b9a7c1fb6dfd212723a71a15b7e3dec45344c82cc9965065fade3d20b89ce981d3d4ff7de0d68219419dc110dd05ed2eb3bc335ffddab94450d317bbf31113a2c6ae8b5fedd422ba50b38c018bafef71cdd8940d3d60fcf74103882949c739869b3ef90c61c81c3303ffed9b616437e2b9a8702ed9709fec4330e997dec102361ac6eeca14409bda3453a58355a572596465d2d66e52794938f918e49af0251c306a0e87e8afbd54a2240299e713b099f51d377611e923ae78acf88ba22173034d246676d07e09a50859061805190bc33cd75250dc883c6ac8cebeed1c1aaf4c53609ad0ff3c44fb8c853a90b398f189144efb39b51f9534953006504e5ec98213443a462d62036f0e1fe0f2b7564a6ba8760536f1e7dbefb6b8496807379d99605f484a4997f0eb613cb0236999b2a6bad12e656d7dd91ddfefb1082a7d11362dc060d6f9afc59cbcf32addaef57da7f36532df2a20cc0bcffd65069a42d608094bc6f0d9411599a087ab149d81a4801c3e3400c775eca52c792a79a6cc67b05fdca9e0276782451baaef50398414a9779d49e146989e52ea6320f97604ab75a840b829debc6c294ec069083bb4bff3f6ca95f3bd5ce9ac3ca304277f6102abf03e6913d898e6e41060fd9eda89b9e9608161d391aaa215c8c0255217f51882222023cbf8fe3a13d1be0cc8f151ae00774cb0969d378fb3d2f750738533205ca3f2353c1ff664a0513de530f78a53e9a8125626fdbccfede71c8c9becede644502b73083c961b86785efb34c33fc34590bbf25bcee19ecb9c000631fa3378966719e77fa14116b38efc78085ce2321c8be0fdb744d590023299cd59c260ab6106ed10c7306274df30cc792f71868b9e50895c6afcd5f748857b4ab328b70fd0ee7786dca1965354c98f32b649db47f46c714ddbc2ddcd6c37302878e9a81db7e4b43b00a7a32cdebe644ee147c22fd97bacea4b59847de1583204a9e0b6614c6a29f2d3186c25804ddbc411f2f8bef3fe268849ad56ed32d92be5d402e910588f4da9e7c509baa0b8bb0bd4afdf8e06f6f48b83a0c1a6459fdc2e7d57520d72cb1fdd7b265bf2e1c1e373905d0cfc7cc7ba382266f39aaad53e32224e4208b45349ad174efefe6f2dcd6e31166df21e5b0ada9348c8b9c42497febd0dfe71abd090abd0b29eef97fec8bb9afcf29945940bddc77b5732add4936bd70bb57130cbbfaf6fac556e9d218acffbca324a8cbd8b1a52ffff64199aef4be83d9a192f60ad9956fcaaee7ee06b6575dd7ba403d7466b45930b52b509d08f479040cec678b169c885418718d8b97663ca703e9b9c3e409b73cec8caef77dbd73f76f52e762e81454f21f42e08b938e28944e83d1d99f1bf81994574cd37bd08066da2e29c6c466273baa31fdba93b62fe176770251a697cbb00603ea1c709d1ec2b4a47167bd239d93fdafff33d678ad5870964a84c8a97fcf7404cf106116aa4f9f615b7e1b75acafe04e686804be31eb6909f3fa89985bbc7321acde05949bb314793c440465c09ce7189a7b793f7f2302c03c5cf646cdb9b820c3a9c4d2731af55f95f1af526016630875234bc66c7ac647772f64f24581df610e4e50ba418b29c417fbb1ebf5ad3cfe10e18ed8dff8a255ee2049b38d673570d49f28c0c1f6955975d0f0afe70edc7828ac582c692a5e7eaf6f287163647882d06a8a9f56f159caa383b18cc5559ed3df33ab06b9ae05c4a20b32663bcc281f04d0d4d2316c5c75c897f36852b58c7afd2455adf17953668f2c1f04fa0590e44bda525e3c34c8521e36428288d6a46fe854726163110454849f3e27ba69435b9d3af6c3592f73dccbd9e44e49c8b67c6742437cdba5bf213b88de40c17138a63c66715a3453a523a85d6366719bd5d473b23c59814cbf45bea6316fd730d886fe69f9507bb1babbc618f7a09b3df8bf76392013e39b43c790fcc0db119521b451295f12800fed4e91087855ffa943d3e6697d73adddeeae5c30e12e4e659703eea1f3e2c4f7a201feacfcb483b0c9f3e82c594ead51da9c3815745e8618b2bbcb428e9e9b296a21ccaa745f27ed3e8c43572437fbf8ed0ac7ccebf132cf26f267c80f4cd7f934e4e437fbf46ca9c8277fa4c09013a9fb24d958da16ae6410060b6a7ba17535313e00f46915e1b0c0040251f74e0afe8ced5505cc1b0ac63c4f67a37c08944011e1c45a8d422424501d40518969548754ccf0b9f019d1dacdecdc35ae36a46d843aa7ee4d1ce4dce45229906daec8d8838d635515a94efc7f8050831da4ae3858d4e02bac2bd16a21cee98495d4b26944ba8ec02af8248f063bebb5e63f0adbc560cc3771acf736709686254c71b6db709a35de67085fc873701c6f811ff9c325db2f2b47eeb4face9bb2c73bc8c0120e056b76ddb60fa78418ef67e137b9e02c1280b46ddc25e61f89b903e5fb1a70459e7550cfa450ef80cbad7afb6bb5325b600f4a9c68e6f4a4fce815b00df68b83253cd5bdd90a640a7771eb60f92d1b79b8d1f012960c67807bb19e66f8bb5af2802d61e748258f40778d2a3c24fb1ac8672528cda8f9279f4e1d1d609559d9c30e9a1bcc952be8081475832b6ee132eafec7d230a0e70aea45efa641431cd2b2ee7a6f476b782c02c213f0d7cd4a24f08156720061d680a736e37ebb2f6327ccf0d7364fb2a061f776aecdb6d0e2e0bebf04ff584fae9bbff5bd4a1c9df59f2506987ec54db78aecf0a3d29453f810b5508e476847b0fc1d088c351f6e79fac68e7c56e5b5759d564a4a2424a2d76619e2c80a5444db47eaf993813b81a646ae9beaa5609e4bb98a2260cee23bdd55b9c3860958ccdb5e3db19468281a75248923284a2a3a47d5969f60074ec1a308d1f52fd3c4e22f98cf35c55f499daf0f36b88ea9968c47cef1246733c48a489668132cbd5ccf0b6e37be5cf445df680f3f8528011ec27d9189213afe4435b0f836533a3f911174af6853e0f40ce513525881bc9a355f31eae9b8c7a4e0fe53a6eda09b2ae86201a3bac6febbd0fd7c3713e66fecd451d93adbe6904a38d7269ff72f5bebac0ffeade82c9339d5838fde7f3b5bf58d1aec3e1f2cf5379475aaf3bba439234f7e8876760fc031186e72f80fb0ee3e2c6cfdf75c0ae7ad7e48ff0cf3f1375305a4fbf793cc0202d25d07ab2a7de4bde954bd6f6ae3120cc461910333d47a5578a011e41013d54266c533fb05f54607cb370458afa3022589000afcdba7035ffd1d8613ade95b848ce01303ff0fd00fc6acbe5cee9b02ffebbe6b6b9bde804b44f3edb0fb76235f4d757349345aa15e8bfef9af751d4617d356e66d7219fbd90841303b021676271e618ac7b543569a6f96b059d6f6d4a840021c7c73a224622a99f9aae43a9e888ec055a9ab86a63c80c660cd89efb82a7439b45e9d5c0aced296449c5578a03331fb2f4a82822bc91851ea67106f7c9d356d0de38e90a9b5d3afc4b105e3ab5eff3e92d1e3457263a24806ae2c9357e2d0818a96c2987c5f0f5e0dc4a7398342dbdb3ad1992684d0b9a09ea36761bd12086576f018d524a54d91f41d28d80423b868d067a6ca42540c5242ae9045bcce2f51b006f2894f0ca8d570ad0524e5c77ef309aba6e826f8495a79a02b26c743686700d67b5f66155ac6cf749aab851d713c4b1260e98158d223e339d1fedd2b3cfd19ec22cc34471284fb8884364b65302a1e1c273f5901313698f459a9abfd4bf89b3717b4e3f384fe18fae38ee223ab6842d294c1a17edfda4a2f8b1308e0d2beac84a9019b7bc76e6909e181654c36a83f077d07a7d1a8fcd639ba5f24d32cbbde7c54da37cf4e13569c8dbe3dc8ebad5a6a28c4927fc05a0567a45864dbd99bc0ea3458c1e4ea8379e27767f353c0dff333677fae3097b60c679e4a93c1fbf3bbc79bede87883f2e227af84892396568f174eddf3ea99cdd891bdc1dda84f43fcb61c157cfa46824c5268e37331014698aa630ec792cfc41b495dd86eb5c79423d26811671f1f04f0111272ebf65af75398354aee93aad45cf7c13b87a0d48c0742c61292509fbb85a08206893b280e3d1c9aa8c52541cd85383ec2450be3af79c6b6c45b1492e3d15563b3d8b067b0f729d8c0819a37fadb7f64fe90844f45e9003537efcafff0106047dd562ca00705428ef5a6c110e6cf93eee7b1292077a1d0638c3ce954f310d3dc1f648f549be74caecf9e25f79a21a836ad4302e706a2048aee1f9eb3aaed1d959ca89d2e812dba8e98b39d05256752293e8822f95545360de66e0717ba571c00b5fbd7f32947df97f1bcddc93693a3d798c79e75cf5ede9e6e61280e83b56bb81128403ce2cfa5b367cef9a8a09cd4e23e4784286fa3f79ea34b921a4ca96c2c0e806521e4b093c33c3ec448af6be1bde1546ac61c7e436fad5eb94f0ef0883dded831f5a912b309546c4abfa438b33164845fae5905a1fcf328864dd16ad824d85bc446cc876282d90f89a7ebf9ec38670d954f75f501319960eb689ae983a8e55940a34c11f044638d1619b5a2dd8ac59a43f5a92774596f5e6f254b161b8122e32856827d36fb7fcd754820f2688b929c0c652ff41dcf74e09d115c35ae083116d578e8152ee6c86d87f6deb9e0b7ae5f8f154b729d32d7a8ab37e40ef17658220463f5a679e14c113853a29576e26ddbd70180720579d4cf3c9bcb29c5bd26fe2cff6fc27cf49c2d1b9d4f2bdb4eac83834c0bd55bf1a7679fb63e2b36eda7a83aab03d271f55c333a995d4faeaa15ffc5e3381269e72dd9be4842bb8b7ac9b5c9ada98519bc987344c8e914d833718d3c0adf04385b5fa366bc44c2e20fcc607059cc06d43911e8f39ac4bc9390cc031bc1925ab6423fd7fbcffaa36db86488cadbc17a92d23a548e72ac333db495b72ddac503bc9b36124c16eda159484af3ec8a60f41e9232870d1c2cb9eac9d2b1e470cb003eab6cbbe3d8b69f15a2c756997a2da3ddb1dd2f8a11e6b7c416e9c3bb3a49955cf4ec7832a7aa7aae3e7bbea5e73658d6109552454c9197d4fee51b7e8582947220340a68fd38e5b230c7d1640fed27f14457f0032e7ee819008cfdca92c20c3aeda99ad1275b054e2c3e18a58b9f9c5b6845bc66b1171fb0593ba01f4e5d142f30a6a8c86a3e2ebcb9c1b96f15eb9e7e9bf1e03f1ede13b0148d90810de1bd24ef865b52e0afd37461b0f20a12cdfb4324bcae5f902f17322541b0cd54e6e139a6e21b050016d05a38a0d8d9b2451f5531b0c30d1d2e79ec747b8d091910df874b7b028431e7973102ae0a0bc5e48f627adedf53156901869e81df510ae5cf89d0410f2b0a6cc31e69895a7551fd01c69f8debde6d29b11f314c58398d695a4fe3605a5749c48aca3e9e2d819d1858a930f2cb3fffc0a28a2720aa22ed585b7f7d5960718c67c7280a471bd2f82a8a1fba0d8d9d792d3d32361739445de69db47b25abf49300702f493f6b4bd69cdfe7eec78153146c0fd545e5f8f8681da0081d94564673e4fc9247421b12fe16dc6f9b3f10c3265a60b65a4dcba93ad7be02b893cb614056dfe0abba30f0418bdf81a6641d9e37606bdc2112c18b4f99f145862f3e557a61dd042191c5b5e99b2fd49c0680031f8a9d73ff62a6975aab64245eb1045aa2c6182407274b1de7c0158aa0e749c898e6b7726a1fed8a9ec9218a2f9c59d1bf6cda80f515fe4589dc2c9b114243a639a73ca6ffeb88a3e4bdfe30de57933b0ab19754aaf1682e34b95f0946886e402cb6f10e93d8468cecc9f5564867cacbb86c1b93be661e2572c3267d52080fefff1089ca9c84c543fa3cd8a9fa0f7615527a9b8744c48ffc1e5d64147654e7954423edcf076bed48cbf9d6f0d079e80719f834353b95d2ae1f62109e235d39f64c38fb295d0c249d5d9b3ede178e4c2a6f70c290c1ce04a7c515600b67ca3f9be84caffa717f92dc5b6ba6bd67ce8c62d62f514028633044c6f0d12ab43895c20d060442af91f175a17d19d45432b7556bcb9891d1ab637d2a3695d513af75711a4f16f17bffa80518fc1ed560959095c9ff2d853a031b15688c4a2d79fe1623a976a76dde4287a9d026fd3374ed4cdcb2fe477bdc9ede675e39b7b1ef0ff39adf56d345106c96dc15b2fa6018f67e831e966b2e238ca32f3f344d04067d809d62028e2951329cbe9052e6d502c4e1a7f707423c70914cba798ec3ecb727626eed7238f5ced9fed4c50012032271013705411ecc4060f6142bb8ba8d79d9f06b5358721de7ef5456c59a8da0c9171ab70068cec82d870e9e91e5c5a2d2bc0846c58093cad4a63fcaf6b93902b8b508e4f9a99bbdd965e3454095a590b7de87eb1ccb3f8a51ce5929dd8963161f2495546f00da015421970e128acc895ac45261c8a46a7c6e0f96362b168c4116234d2a54eda3846d33275d173c26b1a11d6a0b8b53f732e5e6e176c883ad230c11b8f9c0caa695cc97ac955b9e4955e57439a55ee2cf3ed1c3f70abadeb035f2803d983a6109d9b5fecf75514737268d886a49a062b040d05683985aa43f9274804599b40a32f1e479d436e3bdb91ca74e108ac82ad5c2b0699e1df76a7232147d5b38db2312a7c50bd2ad44fa3f85c2cb7ba0976f378ec6b55e72b15809c914be2f705dc34969e194089dc8629abc5a5dde04e515e89f37fedf6e9ce1ae9d1da14b73be2021bab3a79e13a4bbc8e686f1b8508e52e2f60dd2c7349cb09c3976f6235c2ea70607e630dc61690b1327ca517e4b62ec9574a5d8f9fae94163a6043b1e52c10b98ccbc8d48ed3849ff46b96030be6fc955dd9fb1dd78c14c13853491db2ab58e53e86e3dd4d1c3b1f51be7969634816afa434bdbc0606d53d20f3d794d4c2bf50a5d7560fcacce70ce03ea97e85370addfb11037ca39723c7882291e1aef15712d42149b16d277cd928efc65c4964f808c3f7b10fab98604f8822525527bfbd80c8476f8e81d99ae3c082cc57a6469fb1314ae6aa452fbc6c205155f5f8d23fd229e6576fb99d6e50b75bac866c55776d76a505203de739fcab9d03c1c3cae2f414c9f7b537d627a1f64c6b5ca35aeeaa449fe1e60016bd2ac92d0827ac30ffe3f457bb2a88094e887c4c7275c1d464e4aa6a29a707b1e06b1b2f65640d1d303877afeb0ed5b249d18734069d5af27f62d184aa6d030b3e716bff3f4a0f284bde1709feb01ee50febd336fd8545b3107aef332858f8b9472a179cdfd57e444424588b19a94253942591011eabb0204881d2a3dd826b2bcf8462ae57ae22147e5cd04fda93c72c77c84921e7578fbfbfd5453b427f5a5d23e59131cc21fb6233b5cd9af24093cc8ab6de3e131e46e8510cb0e3a14f0551d97e9ec9f268c2af6f6e05540a7402e910182464b5aac6a9098f1bbd3a5071ab4e3a283046b97a49dedd3aff2acb64f75bb7441353b9da4388d5388b8d944eb09e22323802a06e99463469cdd88d67dd4d8db59630ccc23d8ca4a783073dc21d5869aea9eb06b04324981fe50d1e5e03858385469183b8c07c556a28d8c8c8f7b835172b040840f6ea934a6a9190e4473c3ffb424af664e06f56350f09ec49c9f03720a3c839117e61fa3cfd6c40aa5e0a84fbc38a4455dace2de5b21e02bafe20261f154d0a1b38ab8eccb0c96a51a612eed0a8ffbba4ab7216881bcd0ed82b771350c966bff2f34879f6fee4cd4d0882af79b887a9f62e9dfa931dbd5fc9c6abde6945deb2ecc5d1096645688f339997fc6d0f19ae8dd1380299b62cb645e8a1cbd994706e86fcf1f2893d5717f849cc822be20bce6b660605b4b16f35f9857d0dc03891781f207de53ea3c0a25203a16d4117abc9a48cb0a494aaf5bccc3582bc2eb50e37b184c0432310877dd0c9a5872acab2e6248c938b40b1259ab94226bf66dfebb88c8ecc77b881de1678b0f6ac5b1302cb55addcf2c785cddf53a4ba516b977cf2ef782ff2f7fc45eb6190dda3384ecddc08029085e12b57ed9d43b2cfee527c1a4e92a486d325a638964444a369087362dc96cc3b4962a42e13618c162fbc4978beddcfd83420078b71fc4f821fde6f36adde10f6509e96a30ae78a6c180cc068d95ccc75c8424b4eb9bbb8e1e565ce52a4fe4b9618f2eed79ced78beb8ad1cf58c42041833d18ba5e0496e6d986b02568a75345e6ab6a19fd120c73ca5368eb98b9e2c7e52bbb9c55c9100e91fe0454e5c5fedf6d775fc53fa7c7753bb46616b8106b8661fdc9eced828c4eaab9c7714068ce077ae80f438e0472bf046e69e3c78ed36bab2079c9e929cff71867f35a00c99daafdce51c175635c6aaf28f68d354567f12d55ee18d28cba101c8ef520f508dcfa30496984886bb661f8209c88e021599350d4dd792606285057d197206b49b124b9ea306d9793ba913187de72ff205821c80d128bf96fac5a50def2eacb01694f2883cb726753161205213641f723a5ebd5bd4de77fc2b7172a5f155caf2c680049d58fd05169d57060daa25be1f699a59ff27105143f6d7d8f9168f022bbbfb8bd84fac04f4031989d9651a8bcc28bf6b5aa2f1ffe1781c7a8ad8538ca7d295f19bf0e9e70cd9fca4c231c77a24fb16973fd6043ef571a29f0b843de9cf514f093056a071514cc57d0f13c18be5559bcd83837e16f3e87b344945229734b88842cc80f7d827899b5fa7b0406ee6fe269133ad146e1e9d089f1d0869b5bd84d94caa50e230edd2763ff32120c398207ecc178032c7bd6aa03c3362a53784dcb116012194d85ac6d044fd9475b9b7e183ded5f8a384815fd15712449e4d10fb8250e7d3bacf8c37db07cbe928c91a04e014ef08ae5fbf9b85f5fdb2a363f1b73005a77c6bc8835ff10096b35186a642ceee2a5ee2c10b2ae0a20747b947047be7a961ca6da03dd30eedd3444e3d0dba4692e1fbfa6f26f37ab21787d7aec254646ec750346565f63701f32dd221ee6779d8ddc0d796defcba53cb5b776d6fc515e726ea045231d5d5246a6b8e24a0f6f17466a228557bdead0feaae2192657adcbb643f818adc865917a9df3578f17ad63e15a7cff5325db277e2370add56bf06e46e0bd9e98a4ea0c06dbde7af182d3d63ef5cb64a73d3003c9c7bd4ce32d8e7fcdf17e5853dac78bf0cc624f98f139c3d2665eecffeb0990c0c54e6ac0555d9691d02d3c8100b20a7bcd5e69696ba9c7e93f970057ab0ed1cd499af0ae2a5a544e767c87d04602c1f22b3888387791d8433b913a6eabcac559029e93c624bb65f6cac876432039ac6eb734e162fb8136b384e7634f286bf17a3f5fd766926d94ada4fa93c696177faa201aeff24c5ca100c05d184fbf7e6d365bb2b3e5c39ab593e3abfb4e7e451fa1ed0fc000d345a42e58b354eedd15b5c1195d70606fbd139202df1b3e042cd27168fecc6e91ec8a8c273ada27a4ef0b658f59b7db0e267b04af40ee73330d4f3c0579e4b086b29147754682ded19321110f5c1fd10577054937dfcd92f9178dbb7c971b5d60b4a390c281f893c8314fca5e54021da49cebfd5fde2eb4354ce7e2224f9d7654f1b682963f52ad434c3fed51ad834e6187958ef6484ebe9166d196fb1ffc459428b27c86c7f7ad5f2f60532f1f61afc02837462e998ecaa4fb933671ea916642c9b8d3f2ffcd782b376bb353ac5f480946e487ded555d960bde75aa622872bcb5cd902c2c04554c929ba39946d2946987da5480d114a4bf68e5d672890fb93021c9ac4d141e8fd4ed680249e2c050b53d92686cd5dcf597b97e475522202be99a173c097579857ec446bced9195c10703aa16043957d31c6f1d1b7bc605bb205b53d745bf5e9bfcbcef64d13d7d2b9f8b96681f635a554b0399b27925b56c30ec84560f3ff78717c618cdcfc440f39c4e9b9128b4e48de698d28bf53045ad2c0ffa87b7d2e301fd084b55fbc1ed6605a5a64100438d9d3489825cd9ad61f306befa56a4b789afbdd11093e8d800518ae90989ea7536c4422ee23718ddf366ed1e966db0558e063bc8a5ec1531eeb40116b3abb32607bddecd03adad683dcf9e6ce7983d770826bdc590ced0985a34d9dc1823d0f399d4f7da1922124b8900ccca70ff9013d56c6d46279006778efaecd134f4ea1a16de2b7035806e1ae606437d331c9fd73193879c865766959fb23bb83e6e5d44ff3cfe516f48651a65286fb21c7ab000256d2533095d30b2c6e2ff5c8f65134ebf6cc52fc3a350be78f7e85881f694d51e5dcc35aac04f99316bdd14b8873478d8d4af8ce6c6391c8b0c93e3c803405c82e7c281d49a92b1d9c1cd4ee63bd5e3c7243a6eda17c0dc892fe8f93fb15a4901e8f1faa87c98fcf13fc892301800f04bce967e668ef0a5f5050a20551c13f808a18648c1a0986b2fb92cf2a67eac0e8c7df3aa0f4b773797116b28de8e3efee4af1b65c7f758f729393c1960b8f50cac153f0b104f8545275679bb91f4d55405e489f58d9f5d3bfab14aa0c9d40339c90ebd5072f35189e2463d74fe713031dcb6c32ec2d58433fa83971d592902e662d68fb09325014e7e7aadc914bcbd7fd74c3a13c2ef1490dc6e77ebf220dc33950701b4a354fc8d6cdac7a415c930a007cebf8bdcb19015d407ae17de136d2faf15b2c0b019f36f91ef857791fdd98579f35716a2cfb341bed904fa12d0c15804e6b34ed7c92cc3950433a985208f45a6f9630cec3de321cca8470fec0618f364b50479456e43508e9bd5c201b9c48c3f7ab2f2131acea0269985dc9c107aff886ae0f90c176e6b5a353c04f836294eebec635d6e0651a6e8d03e3308f56f0c3bb5105a36557f1847ab6383503a78829822b90e21a6f8fb7d0009c668a61311d491e64dde5818a28b044cda80e5e172cac0c116426cf3b8ff6b29aeb36617b3e85bd377df7fe51ac70e558329b0a95b66e24b261cc8369754dfe7e5d1a735f012847c61c05c0dc6767e1c0e21d0634dd8aebc201ed88aab95dc81cf6b337e6e81e756a095c2489edb51c29e24ad2fd1961ef3a18e3096c338e19209e576ca3395857f32aad8d61f163b275d6427412f6f7b35ec49ece1130be500a4b615b77caa18e3e2086a26f90deec9a13dfdd00f4da3ae903952fefb3705d0f7cd9f6517a55b96d74590a58bdf1fe75794acf72ec34f2914ff9b06ba8aaa36523b6cd7e023d736c5f05352c8c54f08c12a4c503ac5ffc774cd3bc1d9ae7bc0abede38c113e2b47967f1bb349d026e0e255abf7a275fb4a3af3bfa04d2aa3239af1a9384140590d54585fb712c67dfa6ed2c64df9bf59b89eeaf465b749e25a8a518d7e86fb92ab9fdb6533965831b41e37b6e3aa195e122dff27d6cae1bfbda505f63a432ee3c518e314dd00cd9b1f8110e2c450c91da6179a4c3fa858724eb75a07dc54fc86a94229b349892d124686f414c533a347e56a5daa207c621084ff9fcd790ee4d4b1bea739e8da7c2a1b3378174e5343fa76b11fbccba275858b5b18d0e0775135f5b8661a68d7ed2ddf485087f6fb1ed6c53729064c68f799bdea61b59061aed01f81bc65cab0686e464b24d0cf0d1c8299f795fce1d9cf4dcbf005dcdadab5202a241e736dba425579ea20c8793d7e91ac7d4f0567ae39392f96fe4d52e12dc42c5f47b88e2aa8cba4f1cfafa04d0e950cfaf8e191acb2cf0c0bf27286010910c15356d3605add53c0cd57402624770d02888f2b80fa9ad5925984a8f8a431a405546489691ae9bd8d7eed9b81817fb3564a286b05ba8a4a69f79ed46e32e64c79f18938c7f584c47c440f916ace4af5e1701c2da1aee64536d3d4527138da730105c649af527fb36d0de6c872071301841af632c7df165a55fe49830cb35d5f2330150afc8ac8c97fa07ea060bcfca3c04951896f8999930ca715b5c37448d7b39834d95e0212133e0c51ae19ef2b7af804e937787f250c5cfb5091a1d4e4ee9319238dca18d54a849aa9f36b8e261c296533a520b4c3f4c90c027f4359f37a38b884d30eea0856c217a0bdfcce56c502b4c045b5ec2b2920fb15a0d6533d760e83a9b21c7b91ea0a21541de0c7b38ab7a10b767ae9d08a2dfdbbe8941a9c59bef9cfe1c34e283310bbafedb5ab3c2093f3d89d97a69fd0198a1b27b5c53608f296df8eccbc6b5aaf2459d67dfdb09eca97abdbf572e62709b3953f69926c6473de83a0bdd234d004ba524ecbac131e5c997e5633b172bf9467e2f1843ebab16501d9bad1db51c32eec0805c6ec375c058af0aa461141b2f75d4f7918c42769184571c5610c26861bfe8189a646a70fdaf1e50e911972a4e1f525ed9a8581ab9300acc59b160c4fea81f90c5b8b917be78d780fc581dff276c4656ad1eef23cf0498045221d215c04115d11c4cda2457dd1e13702792e6336ceae66d26294de7d0617e2006f15da851681eefb16e2d38a0d095f7ecadcae560fd374b9acd304ae4fdcf995d917a851f8b33400a1c9db2a062bc1d6e40605275fa6d2c6b7d57270bb18530a00bc7dd92c69970e19ebce1d782dcff9a47d5c4ed724bbd94bad6cefbffa935801a5f9b8b38cb916c4810e2ddf28e53d2763d9766ee8c182c96ae0bc8ac81fda7ec30c2716d04ee14349a581e5506268d3de7d93de41133b2cc47e036eb432f2873c60566269ca8582fce696fa926b68ef067339f371ac681564b6519618640dd64fe801a09f34cafe17f79a6e65cc412eb98c55f6b6bc0a3c8ce04d51f3782906533810313c91da0782e6d80dae91c6700fb371cf92c7eb14cdc73e6171dec0d4e66acfc098a0b891bbecc1cbb242ea911d0baff25e8d597bdee6296b16743f13dc0251e2c27a29910693bc7d5bdbcbf646cea3b13f0ce698749c5bc932aef514edff713c884bbb5fed2e92154a4e7a4133bb698e972ea2772d8aa9ea95635aad7e7f7816b699bf464ce48c4f445c77ab3d92d6c061fa174c65ecbcb0634824988253086a85f6de862b5435057b336ae4c03188801ebf3f926e02d6462c5cda181951dac1163764eeebe3964671298bac2b3feee8172c23891b6b7cead81020d9d3ccdba20bed39ac7c59a3c4330fd8e3acda9db15fa7f306b60b60a1e4cee796c150b0fb6e50b77f94bfec4dbc3df997006528e404a78e8af4fa8f1cadc71c2afd5d5e43b2302ac4332cb6c480fa647b3fc935f87c750fc317514302aa79726738ef5a3ba15b1f06be452436c41d185d0b9e09652c02e88412bdeae3e7fe164050c7413a06105c9863cb1070422a434ed4c8b0da96cbae5793b80d06575e88b7c523a765a3c1b3a45eedcac4902a8bc7bebb6baeafa53391ff8d29c38f129c68621973881dc0b15a5e4f8465cdcd3eaf909b157c80955a2a27022162521d0917593b38cdcf911bdeeea44cfbc756cd935eb75b6d2e09dc2cf56742abfb68e110b334ff49ce2e4a3b20f6fd62823eef59fba9a204cd768cf7a95739617846d8d17d5643be0065cb027a118e81f1c963629c0085bfc23d34e1f7526391d44b1f1e3eef8aed2b3e3659245fb680f992ce2a6922a7ffe101eeaa9918639958d5c2d938444c8e0dca4eb5c5b1a9160bfb7d85f796983c490acc056cae3b0b203fca510d60f18302c81ef4d7968e9e446493cdb87a340877f39c349968d09f085638d7d4b2339594bf4c27f9b3fe81eea3d347fef939557352a5eb35b62ccb4b14e66cebd430d0f69c95beb078a3a2de13b44a16c38181565ae81d1a09381217ca454015f69c4f682a1a46df87e900debff469a6192d4fe1f813e31a8c0b1e7b016add719adc35bb48eafc928b817294a0d732460be38f0cf25c770a7e49a12482912b5de73add26db30f03621d161cf69335fbe562d003fa1b88869fc57125948d6313755fd3370266442af27213b35585c4b67faa91c8540a8e3cba98c3136ef7b7bb5969807ee7aa69e30517af77f4a5718cc4110c3b81126fd79754b48e63f3a5ff0e4d12d4430bd2ca427a0732945b6f0e8d26d91c157772b31e47ba9aaa602729e87279ab880b75b08f4ea3abc9add1db05aecbf464e3b787c916db602d6151f1a1963d8fd985f065279b9cd4d7e8d76bc8e678828f0825fce65d2bb043f1f2db6d0560c0b680225f5cb06501d2a062a73f2941b88525f7118c965380e0b7921f5dc50b57ad7a295353559623f286a48ab359de2a2032d1bbc694a626b5743bf61cd2001748bae4f661aeef2b80f82aeed9b62a56236b2e385a99ed7704b1342cedca89b6911765a8bcff2fd9469dc1faaddbb562e023193de2e194ffa13546cad4fe527982c0f9bcfce8a6fb1fec181704e9f6e4591d989e0a5d8b9b25fe6c8cf2e4826dc71a5427418b4b274a24b92b5b39841562a373d1492a04d06761bf37804aace0c936ae0962675e34c49e876be97bdf14b9c060d214ec849d6178be22024c8dd0afaecc855e610a943f3305b921a755353a2827405b44f681d6f0e99dbc72764969db01531e576ee59cf5869cbc1477b0e0e383d50bb9b3fedd1ecbfe84a4802b40003414fad56070bdb3049ce90ed1b83ba4d4e623e2889c698092f28560974dd64230360a51784e519a79de65ab7bd7f");
        assertTrue(Hex.toHexString(s), Arrays.areEqual(expected, s));

        sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSphincsRandomSigSHAKE()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.shake_256f_robust, new SecureRandom());

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initSign(kp.getPrivate(), new SecureRandom());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    public void testSphincsRandomSigSHAKE_Simple()
        throws Exception
    {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("SPHINCSPlus", "BCPQC");

        kpg.initialize(SPHINCSPlusParameterSpec.shake_256f, new SecureRandom());

        KeyPair kp = kpg.generateKeyPair();

        Signature sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initSign(kp.getPrivate(), new SecureRandom());

        sig.update(msg, 0, msg.length);

        byte[] s = sig.sign();

        sig = Signature.getInstance("SPHINCSPlus", "BCPQC");

        sig.initVerify(kp.getPublic());

        sig.update(msg, 0, msg.length);

        assertTrue(sig.verify(s));
    }

    private static class RiggedRandom
        extends SecureRandom
    {
        public void nextBytes(byte[] bytes)
        {
            for (int i = 0; i != bytes.length; i++)
            {
                bytes[i] = (byte)(i & 0xff);
            }
        }
    }
}

